o
    h                     @  sN
  U d dl mZ d dlZd dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dl m!Z! d dl m"Z" d dl m#Z# d dl m$Z$ d dl m%Z% d dl m&Z& d dl m'Z' d dl m(Z( d dl m)Z) d d l m*Z* d d!l m+Z+ d d"l m,Z, d d#l m-Z- d d$l m.Z. d d%l m/Z/ d d&l m0Z0 d d'l m1Z1 d d(l m2Z2 d d)l m3Z3 d d*l m4Z4 d d+l m5Z5 d d,l m6Z6 d d-l m7Z7 d d.l8m9Z9 d d/l8m:Z: d d0l8m;Z; erd d1l<m=Z= d d2lm>Z? d dl@ZAd dlBZCd d3lDmEZE d d4lDmFZF d d5lDmGZG d d6lDmHZH d d7lDmIZI d d8lDmJZJ d d9lKmLZL d d:lKmMZM d d;lKmNZN d d<lKmOZO d d=lKmPZP d d>lKmQZQ d d?lKmRZR d d@lSmTZT d dAlUmVZV d dBlUmWZW d dClXmYZY d dDlXmZZZ d dEl[m\Z\ d dFl[m]Z] d dGl^m_Z_ d dHl`maZa d dIlbmcZc d dJlbmdZd d dKlbmeZe d dLlbmfZf d dMlbmgZg d dNlbmhZh d dOlbmiZi d dPlbmjZj d dQlbmkZk d dRlbmlZl d dSlbmmZm d dTlbmnZn d dUlbmoZo d dVlbmpZp d dWlbmqZq d dXlbmrZr edYee]e e\e eae f dZZsed[Zted\Zued]Zved^Zwed_d`dZZxeGdaZyedbZzG dcdd ddeZ{G dedf dfeZ|G dgdh dheZ}G didj djeZ~G dkdl dleZG dmdn dne~eeZG dodp dpe}eeZG dqdr dreZedsdtduZedvdtduZedwdpdZZdxZdyedz< G d{d| d|ee ZG d}d~ d~ee ZG dd deZG dd deZejdejdejdejdejdejdejdejdejdejdi
Zded< dddZdddZdddZdddZdddZdddZdddZdddZdddZdddZedddZedddZedddZedddZedddZedddZedddZdddZddd҄ZdddׄZdddۄZ	dddܜdddZdddZdddZdddZdddZdddZdddZddd ZdddZdÐddZdĐddZdŐddZdƐddZdǐddZdȐddZdɐddZdʐddZdːd!d"Zd̐d%d&Zd͐d'd(Zdΐd+d,Zdϐd1d2Zd3d4d5dАd9d:Zdѐd?d@ZdҐdCdDZdӐdGdHZdԐdIdJZdՐdPdQZd֐dYdZZdאd\d]Zdؐd`daZÐdِdcddZĐdڐdfdgZŐdېdjdkZƐdܐdndoZǐdݐdrdsZȐdސdvdwZɐdߐdydzZʐdd|d}ZːdddZ̐dddZ͐dddZΐdddZϐdddZerd dlZejҐdkrd dlmZ nd dlDmZ ndddZG dd dZԐdddZG dd dZ֐dddZdS (      )annotationsN)timezone)Enum)autowraps)	find_spec)getattr_static)	token_hex)TYPE_CHECKING)Any)Callable)	Container)Iterable)Literal)Protocol)Sequence)TypeVar)Union)cast)overload)warn)get_cudf)get_dask)get_dask_dataframe)
get_duckdb)get_ibis)	get_modin)	get_numpy)
get_pandas)
get_polars)get_pyarrow)get_pyspark)get_pyspark_sql)get_sqlframe)is_cudf_series)is_modin_series)is_narwhals_series)is_numpy_array_1d)is_pandas_dataframe)is_pandas_like_dataframe)is_pandas_like_series)is_pandas_series)is_polars_series)is_pyarrow_chunked_array)ColumnNotFoundError)DuplicateError)InvalidOperationError)
ModuleType)AbstractSet)Concatenate)LiteralString)	ParamSpec)Self)	TypeAlias)TypeIs)CompliantExpr)CompliantExprT)CompliantFrameT)CompliantSeriesOrNativeExprT_co)CompliantSeriesT)NativeFrameT_co)NativeSeriesT_co)	EvalNames)EagerAllowedImplementation	Namespace)ArrowStreamExportable)IntoArrowTable	DataFrame	LazyFrameDTypeSeries)CompliantDataFrame)CompliantLazyFrame)CompliantSeries)DataFrameLike)DTypes)IntoSeriesT)MultiIndexSelector)SingleIndexSelector)SizedMultiIndexSelector)SizeUnit)SupportsNativeNamespace)TimeUnit)_1DArray)_SliceIndex)
_SliceName)
_SliceNoneFrameOrSeriesT)bound_T_T1_T2_T3_FnzCallable[..., Any]PRc                   @     e Zd ZU ded< dS )_SupportsVersionstr__version__N__name__
__module____qualname____annotations__ rq   rq   B/var/www/vscode/kcb/lib/python3.10/site-packages/narwhals/utils.pyri   n   s   
 ri   c                   @  s   e Zd Zd	d
ddZdS )_SupportsGetNinstancer   owner
Any | Nonereturnc                C     d S Nrq   )selfrt   ru   rq   rq   rr   __get__r   s    z_SupportsGet.__get__ry   )rt   r   ru   rv   rw   r   )rm   rn   ro   r{   rq   rq   rq   rr   rs   q   s    rs   c                   @  rh   )_StoresImplementationImplementation_implementationNrl   rq   rq   rq   rr   r|   t      
 r|   c                   @  rh   )_StoresBackendVersiontuple[int, ...]_backend_versionNrl   rq   rq   rq   rr   r   x   r   r   c                   @  rh   )_StoresVersionVersion_versionNrl   rq   rq   rq   rr   r   |   r   r   c                   @     e Zd ZdZdS )_LimitedContextzRProvides 2 attributes.

        - `_backend_version`
        - `_version`
        Nrm   rn   ro   __doc__rq   rq   rq   rr   r          r   c                   @  r   )_FullContextznProvides 3 attributes.

        - `_implementation`
        - `_backend_version`
        - `_version`
        Nr   rq   rq   rq   rr   r      r   r   c                   @  s   e Zd ZedddZdS )_StoresColumnsrw   Sequence[str]c                 C  rx   ry   rq   rz   rq   rq   rr   columns      z_StoresColumns.columnsN)rw   r   )rm   rn   ro   propertyr   rq   rq   rq   rr   r      s    r   
NativeT_coT)	covariantCompliantT_co	_ContextTz&Callable[Concatenate[_ContextT, P], R]r8   _Methodc                   @     e Zd ZdZedddZdS )_StoresNativezProvides access to a native object.

    Native objects have types like:

    >>> from pandas import Series
    >>> from pyarrow import Table
    rw   r   c                 C     dS )zReturn the native object.Nrq   r   rq   rq   rr   native      z_StoresNative.nativeN)rw   r   )rm   rn   ro   r   r   r   rq   rq   rq   rr   r          r   c                   @  r   )_StoresCompliantzProvides access to a compliant object.

    Compliant objects have types like:

    >>> from narwhals._pandas_like.series import PandasLikeSeries
    >>> from narwhals._arrow.dataframe import ArrowDataFrame
    rw   r   c                 C  r   )zReturn the compliant object.Nrq   r   rq   rq   rr   	compliant   r   z_StoresCompliant.compliantN)rw   r   )rm   rn   ro   r   r   r   rq   rq   rq   rr   r      r   r   c                   @  s   e Zd Ze Ze ZdS )r   N)rm   rn   ro   r   V1MAINrq   rq   rq   rr   r      s    
r   c                   @  s,  e Zd ZdZe Z	 e Z	 e Z	 e Z	 e Z		 e Z
	 e Z	 e Z	 e Z	 e Z	 e Z	 ed3ddZed4ddZed5ddZd6ddZd7ddZd7ddZd7ddZd7ddZd7ddZd7ddZd7d d!Zd7d"d#Zd7d$d%Zd7d&d'Zd7d(d)Zd7d*d+Z e!d8d-d.Z"d9d0d1Z#d2S ):r}   z?Implementation of native object (pandas, Polars, PyArrow, ...).cls
type[Self]native_namespacer2   rw   c                 C  sb   t  tjt tjt tjt tjt	 tj
t tjt tjt tjt tjt tji
}||tjS )zInstantiate Implementation object from a native namespace module.

        Arguments:
            native_namespace: Native namespace.

        Returns:
            Implementation.
        )r   r}   PANDASr   MODINr   CUDFr!   PYARROWr#   PYSPARKr    POLARSr   DASKr   DUCKDBr   IBISr$   SQLFRAMEgetUNKNOWN)r   r   mappingrq   rq   rr   from_native_namespace   s   z$Implementation.from_native_namespacebackend_namerj   c                 C  s<   t jt jt jt jt jt jt jt jt j	t j
d
}||t jS )zInstantiate Implementation object from a native namespace module.

        Arguments:
            backend_name: Name of backend, expressed as string.

        Returns:
            Implementation.
        )
pandasmodincudfpyarrowpysparkpolarsdaskduckdbibissqlframe)r}   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   rq   rq   rr   from_string   s   zImplementation.from_stringbackend!str | Implementation | ModuleTypec                 C  s,   t |tr
| |S t |tr|S | |S )zInstantiate from native namespace module, string, or Implementation.

        Arguments:
            backend: Backend to instantiate Implementation from.

        Returns:
            Implementation.
        )
isinstancerj   r   r}   r   )r   r   rq   rq   rr   from_backend  s   
zImplementation.from_backendc                 C  s   | t ju rddl}|S | t ju rddl}|jS | t ju r"ddl}|S | t ju r-ddl}|S | t j	u r9ddl
}|jS | t ju rDddl}|S | t ju rPddl}|jS | t ju r[ddl}|S | t ju rfddl}	|	S d}
t|
)zyReturn the native namespace module corresponding to Implementation.

        Returns:
            Native module.
        r   NzNot supported Implementation)r}   r   r   r   modin.pandasr   r   r   r   r   pyspark.sqlsqlr   r   r   dask.dataframe	dataframer   r   r   r   AssertionError)rz   pdr   r   par   plr   r   r   msgrq   rq   rr   to_native_namespace   s:   








z"Implementation.to_native_namespaceboolc                 C  
   | t ju S )a^  Return whether implementation is pandas.

        Returns:
            Boolean.

        Examples:
            >>> import pandas as pd
            >>> import narwhals as nw
            >>> df_native = pd.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_pandas()
            True
        )r}   r   r   rq   rq   rr   	is_pandasP     
zImplementation.is_pandasc                 C  s   | t jt jt jhv S )as  Return whether implementation is pandas, Modin, or cuDF.

        Returns:
            Boolean.

        Examples:
            >>> import pandas as pd
            >>> import narwhals as nw
            >>> df_native = pd.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_pandas_like()
            True
        )r}   r   r   r   r   rq   rq   rr   is_pandas_like`  s
   zImplementation.is_pandas_likec                 C  s   | t jt jhv S )ap  Return whether implementation is pyspark or sqlframe.

        Returns:
            Boolean.

        Examples:
            >>> import pandas as pd
            >>> import narwhals as nw
            >>> df_native = pd.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_spark_like()
            False
        )r}   r   r   r   rq   rq   rr   is_spark_liket  s   zImplementation.is_spark_likec                 C  r   )a^  Return whether implementation is Polars.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_polars()
            True
        )r}   r   r   rq   rq   rr   	is_polars  r   zImplementation.is_polarsc                 C  r   )a[  Return whether implementation is cuDF.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_cudf()
            False
        )r}   r   r   rq   rq   rr   is_cudf  r   zImplementation.is_cudfc                 C  r   )a]  Return whether implementation is Modin.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_modin()
            False
        )r}   r   r   rq   rq   rr   is_modin  r   zImplementation.is_modinc                 C  r   )aa  Return whether implementation is PySpark.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_pyspark()
            False
        )r}   r   r   rq   rq   rr   
is_pyspark  r   zImplementation.is_pysparkc                 C  r   )aa  Return whether implementation is PyArrow.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_pyarrow()
            False
        )r}   r   r   rq   rq   rr   
is_pyarrow  r   zImplementation.is_pyarrowc                 C  r   )a[  Return whether implementation is Dask.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_dask()
            False
        )r}   r   r   rq   rq   rr   is_dask  r   zImplementation.is_daskc                 C  r   )a_  Return whether implementation is DuckDB.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_duckdb()
            False
        )r}   r   r   rq   rq   rr   	is_duckdb  r   zImplementation.is_duckdbc                 C  r   )a[  Return whether implementation is Ibis.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_ibis()
            False
        )r}   r   r   rq   rq   rr   is_ibis  r   zImplementation.is_ibisc                 C  r   )ac  Return whether implementation is SQLFrame.

        Returns:
            Boolean.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>> df_native = pl.DataFrame({"a": [1, 2, 3]})
            >>> df = nw.from_native(df_native)
            >>> df.implementation.is_sqlframe()
            False
        )r}   r   r   rq   rq   rr   is_sqlframe  r   zImplementation.is_sqlframer5   c                 C  sH   t jdt jdt jdt jdt jdt jdt jdt jdt j	d	t j
d
i
}||  S )zHFriendly name for errors.

        Returns:
            String.
        PandasPolarsDaskIbisModincuDFPyArrowPySparkDuckDBSQLFrame)r}   r   r   r   r   r   r   r   r   r   r   )rz   r   rq   rq   rr   _alias  s   zImplementation._aliasr   c                 C  sn   |   }| tjtjtjhvr|}t	|S | tju r t }t	|S | tju r,t }t	|S dd l}|j}t	|S Nr   )
r   r}   r   r   r   r"   r   sqlframe._versionr   parse_version)rz   r   into_versionr   rq   rq   rr   r   )  s"   	

zImplementation._backend_versionN)r   r   r   r2   rw   r}   )r   r   r   rj   rw   r}   )r   r   r   r   rw   r}   )rw   r2   )rw   r   )rw   r5   )rw   r   )$rm   rn   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rq   rq   rq   rr   r}      s\    

0










r}   )r         )   
   )   )r      )r      r   )i        )   )r      r   z%dict[Implementation, tuple[int, ...]]MIN_VERSIONSimplementationbackend_versionr   rw   Nonec                 C  s2   |t |   }k rd|  d| d| }t|d S )NzMinimum version of z supported by Narwhals is z	, found: )r   
ValueError)r   r   min_versionr   rq   rq   rr   validate_backend_versionK  s   r   versionrS   c                 C  sF   | t ju rddlm} |S | t ju rddlm} |S d|  }t|)Nr   )dtypesCongratulations, you have entered unreachable code.
Please report an issue at https://github.com/narwhals-dev/narwhals/issues.
Version: )r   r   narwhalsr   r   narwhals.stable.v1r   )r   r   	v1_dtypesr   rq   rq   rr   import_dtypes_moduleS  s   

r  objVersion | _StoresVersionc                C  s<   t | tr| S t| dr| jS dt dt| j}t|)Nr   z	Expected z	 but got )r   r   _hasattr_staticr   typerm   	TypeError)r  r   rq   rq   rr   _into_versione  s   

r  type[Namespace[Any]]c                C  sN   t | } | tju rddlm} |S | tju rddlm} |S d|  }t|)Nr   rC   r  )r  r   r   narwhals._namespacerD   r   narwhals.stable.v1._namespacer   )r   rD   r   rq   rq   rr   import_namespacen  s   

r  textrj   prefixc                 C  s   |  |r| t|d  S | S ry   )
startswithlen)r  r  rq   rq   rr   remove_prefix  s   
r  suffixc                 C  s    |  |r| d t|  S | S ry   )endswithr  )r  r  rq   rq   rr   remove_suffix  s   
r  argsr   	list[Any]c                 C  s*   t t| dkrt| d r| d S | S )Nr   r   )listr  _is_iterable)r  rq   rq   rr   flatten  s   *r  argc                 C  s   t | ttfs
| fS | S ry   )r   r  tuple)r  rq   rq   rr   tupleify  s   r  Any | Iterable[Any]r   c                 C  s   ddl m} t| st| rdt|  d}t|t  }d ur:t| |j|j|j	|j
fr:dt|  d}t|t| toGt| tt|f S )Nr   rM   z(Expected Narwhals class or scalar, got: z2. Perhaps you forgot a `nw.from_native` somewhere?z`.

Hint: Perhaps you
- forgot a `nw.from_native` somewhere?
- used `pl.col` instead of `nw.col`?)narwhals.seriesrN   r)   r,   r	  r
  r    r   ExprrH   rJ   r   rj   bytes)r  rN   r   r   rq   rq   rr   r    s   r  #str | ModuleType | _SupportsVersionc                 C  s:   t | tr| n| j}tdd|}tdd |dD S )zSimple version parser; split into a tuple of ints for comparison.

    Arguments:
        version: Version string, or object with one, to parse.

    Returns:
        Parsed version number.
    z(\D?dev.*$) c                 s  s"    | ]}t td d|V  qdS )z\Dr%  N)intresub).0vrq   rq   rr   	<genexpr>  s     z parse_version.<locals>.<genexpr>.)r   rj   rk   r'  r(  r  split)r   version_strrq   rq   rr   r     s   r   
obj_or_clsr	  cls_or_tupletype[_T]TypeIs[type[_T]]c                 C  rx   ry   rq   r/  r0  rq   rq   rr   isinstance_or_issubclass  r   r4  object | typeTypeIs[_T | type[_T]]c                 C  rx   ry   rq   r3  rq   rq   rr   r4    r   tuple[type[_T1], type[_T2]]TypeIs[type[_T1 | _T2]]c                 C  rx   ry   rq   r3  rq   rq   rr   r4    r   #TypeIs[_T1 | _T2 | type[_T1 | _T2]]c                 C  rx   ry   rq   r3  rq   rq   rr   r4    r   &tuple[type[_T1], type[_T2], type[_T3]]TypeIs[type[_T1 | _T2 | _T3]]c                 C  rx   ry   rq   r3  rq   rq   rr   r4    r   /TypeIs[_T1 | _T2 | _T3 | type[_T1 | _T2 | _T3]]c                 C  rx   ry   rq   r3  rq   rq   rr   r4    r   tuple[type, ...]TypeIs[Any]c                 C  rx   ry   rq   r3  rq   rq   rr   r4    r   c                 C  s>   ddl m} t| |rt| |S t| |pt| tot| |S )Nr   rK   )narwhals.dtypesrL   r   r	  
issubclass)r/  r0  rL   rq   rq   rr   r4    s   


itemsIterable[Any]c                   sd   ddl m  ddl m t fdd| D s"tfdd| D r$d S ddd	 | D  }t|)
Nr   rG   rI   c                 3      | ]}t | V  qd S ry   r   r)  itemrG   rq   rr   r+        z$validate_laziness.<locals>.<genexpr>c                 3  rC  ry   rD  rE  rI   rq   rr   r+    rG  zGThe items to concatenate should either all be eager, or all lazy, got: c                 S  s   g | ]}t |qS rq   )r	  rE  rq   rq   rr   
<listcomp>  s    z%validate_laziness.<locals>.<listcomp>)narwhals.dataframerH   rJ   allr
  )rA  r   rq   )rH   rJ   rr   validate_laziness  s   rK  lhsrhs-Series[Any] | DataFrame[Any] | LazyFrame[Any]c                 C  s  ddl m} ddlm} ddd	}td| }td|}tt|d
d|rLtt|d
d|rL||jjj	 ||jjj	 |
|j|jjj|jjj	 S tt|d
d|r}tt|dd|r}||jjj	 ||jjj	 |
|j|jjj|jjj	 S tt|dd|rtt|d
d|r||jjj	 ||jjj	 |
|j|jjj|jjj	 S tt|dd|rtt|dd|r||jjj	 ||jjj	 |
|j|jjj|jjj	 S t|t|krdt| dt| }t|| S )a  Align `lhs` to the Index of `rhs`, if they're both pandas-like.

    Arguments:
        lhs: Dataframe or Series.
        rhs: Dataframe or Series to align with.

    Returns:
        Same type as input.

    Notes:
        This is only really intended for backwards-compatibility purposes,
        for example if your library already aligns indices for users.
        If you're designing a new library, we highly encourage you to not
        rely on the Index.
        For non-pandas-like inputs, this only checks that `lhs` and `rhs`
        are the same length.

    Examples:
        >>> import pandas as pd
        >>> import polars as pl
        >>> import narwhals as nw
        >>> df_pd = pd.DataFrame({"a": [1, 2]}, index=[3, 4])
        >>> s_pd = pd.Series([6, 7], index=[4, 3])
        >>> df = nw.from_native(df_pd)
        >>> s = nw.from_native(s_pd, series_only=True)
        >>> nw.to_native(nw.maybe_align_index(df, s))
           a
        4  2
        3  1
    r   )PandasLikeDataFrame)PandasLikeSeriesindexr   rw   r   c                 S  s   | j s	d}t|d S )Nz'given index doesn't have a unique index)	is_uniquer   )rQ  r   rq   rq   rr   _validate_index   s   z*maybe_align_index.<locals>._validate_index_compliant_frameN_compliant_seriesz6Expected `lhs` and `rhs` to have the same length, got z and )rQ  r   rw   r   )narwhals._pandas_like.dataframerO  narwhals._pandas_like.seriesrP  r   r   getattrrT  r   rQ  _with_compliant_with_nativelocrU  r  r   )rL  rM  rO  rP  rS  lhs_anyrhs_anyr   rq   rq   rr   maybe_align_index  s~   !


r^  -DataFrame[Any] | LazyFrame[Any] | Series[Any]rv   c                 C  s,   t d| }| }t|st|r|jS dS )a  Get the index of a DataFrame or a Series, if it's pandas-like.

    Arguments:
        obj: Dataframe or Series.

    Returns:
        Same type as input.

    Notes:
        This is only really intended for backwards-compatibility purposes,
        for example if your library already aligns indices for users.
        If you're designing a new library, we highly encourage you to not
        rely on the Index.
        For non-pandas-like inputs, this returns `None`.

    Examples:
        >>> import pandas as pd
        >>> import polars as pl
        >>> import narwhals as nw
        >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [4, 5]})
        >>> df = nw.from_native(df_pd)
        >>> nw.maybe_get_index(df)
        RangeIndex(start=0, stop=2, step=1)
        >>> series_pd = pd.Series([1, 2])
        >>> series = nw.from_native(series_pd, series_only=True)
        >>> nw.maybe_get_index(series)
        RangeIndex(start=0, stop=2, step=1)
    r   N)r   	to_nativer*   r+   rQ  )r  obj_any
native_objrq   rq   rr   maybe_get_index[  s
   
rc  )rQ  column_namesstr | list[str] | NonerQ  6Series[IntoSeriesT] | list[Series[IntoSeriesT]] | Nonec                  s   ddl m  td| }| }|dur|durd}t||s)|du r)d}t||durAt|r: fdd|D n |d	d
}n|}t|rS||j|	|S t
|rzddlm	} |red}t||||| jj| jjd}||j|S |S )a  Set the index of a DataFrame or a Series, if it's pandas-like.

    Arguments:
        obj: object for which maybe set the index (can be either a Narwhals `DataFrame`
            or `Series`).
        column_names: name or list of names of the columns to set as index.
            For dataframes, only one of `column_names` and `index` can be specified but
            not both. If `column_names` is passed and `df` is a Series, then a
            `ValueError` is raised.
        index: series or list of series to set as index.

    Returns:
        Same type as input.

    Raises:
        ValueError: If one of the following condition happens:

            - none of `column_names` and `index` are provided
            - both `column_names` and `index` are provided
            - `column_names` is provided and `df` is a Series

    Notes:
        This is only really intended for backwards-compatibility purposes, for example if
        your library already aligns indices for users.
        If you're designing a new library, we highly encourage you to not
        rely on the Index.

        For non-pandas-like inputs, this is a no-op.

    Examples:
        >>> import pandas as pd
        >>> import polars as pl
        >>> import narwhals as nw
        >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [4, 5]})
        >>> df = nw.from_native(df_pd)
        >>> nw.to_native(nw.maybe_set_index(df, "b"))  # doctest: +NORMALIZE_WHITESPACE
           a
        b
        4  1
        5  2
    r   r`  r   Nz8Only one of `column_names` or `index` should be providedz3Either `column_names` or `index` should be providedc                   s   g | ]} |d dqS )Tpass_throughrq   )r)  idxrg  rq   rr   rH        z#maybe_set_index.<locals>.<listcomp>Trh  )	set_indexz/Cannot set index using column names on a Series)r   r   )narwhals.translater`  r   r   r  r*   rY  rT  rZ  rl  r+   narwhals._pandas_like.utilsrU  r~   r   )r  rd  rQ  df_anyrb  r   keysrl  rq   rg  rr   maybe_set_index  s@   /

rq  c                 C  s   t d| }| }t|r%| }t||r|S ||j|jddS t	|rA| }t||r4|S ||j
|jddS |S )a  Reset the index to the default integer index of a DataFrame or a Series, if it's pandas-like.

    Arguments:
        obj: Dataframe or Series.

    Returns:
        Same type as input.

    Notes:
        This is only really intended for backwards-compatibility purposes,
        for example if your library already resets the index for users.
        If you're designing a new library, we highly encourage you to not
        rely on the Index.
        For non-pandas-like inputs, this is a no-op.

    Examples:
        >>> import pandas as pd
        >>> import polars as pl
        >>> import narwhals as nw
        >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [4, 5]}, index=([6, 7]))
        >>> df = nw.from_native(df_pd)
        >>> nw.to_native(nw.maybe_reset_index(df))
           a  b
        0  1  4
        1  2  5
        >>> series_pd = pd.Series([1, 2])
        >>> series = nw.from_native(series_pd, series_only=True)
        >>> nw.maybe_get_index(series)
        RangeIndex(start=0, stop=2, step=1)
    r   T)drop)r   r`  r*   __native_namespace___has_default_indexrY  rT  rZ  reset_indexr+   rU  )r  ra  rb  r   rq   rq   rr   maybe_reset_index  s"   


rv  r   TypeIs[pd.RangeIndex]c                 C  s   t | |jS ry   )r   
RangeIndex)r  r   rq   rq   rr   _is_range_index  s   ry  native_frame_or_seriespd.Series[Any] | pd.DataFramec                 C  s2   | j }t||o|jdko|jt|ko|jdkS )Nr   r   )rQ  ry  startstopr  step)rz  r   rQ  rq   rq   rr   rt    s   
rt  kwargs
bool | strc                 O  sb   t d| }| }t|r||j|j|i |S t|r/||j|j|i |S |S )aW  Convert columns or series to the best possible dtypes using dtypes supporting ``pd.NA``, if df is pandas-like.

    Arguments:
        obj: DataFrame or Series.
        *args: Additional arguments which gets passed through.
        **kwargs: Additional arguments which gets passed through.

    Returns:
        Same type as input.

    Notes:
        For non-pandas-like inputs, this is a no-op.
        Also, `args` and `kwargs` just get passed down to the underlying library as-is.

    Examples:
        >>> import pandas as pd
        >>> import polars as pl
        >>> import narwhals as nw
        >>> import numpy as np
        >>> df_pd = pd.DataFrame(
        ...     {
        ...         "a": pd.Series([1, 2, 3], dtype=np.dtype("int32")),
        ...         "b": pd.Series([True, False, np.nan], dtype=np.dtype("O")),
        ...     }
        ... )
        >>> df = nw.from_native(df_pd)
        >>> nw.to_native(
        ...     nw.maybe_convert_dtypes(df)
        ... ).dtypes  # doctest: +NORMALIZE_WHITESPACE
        a             Int32
        b           boolean
        dtype: object
    r   )	r   r`  r*   rY  rT  rZ  convert_dtypesr+   rU  )r  r  r  ra  rb  rq   rq   rr   maybe_convert_dtypes  s   
$r  szr&  unitrX   int | floatc                 C  s^   |dv r| S |dv r| d S |dv r| d S |dv r| d S |dv r&| d	 S d
|}t |)zScale size in bytes to other size units (eg: "kb", "mb", "gb", "tb").

    Arguments:
        sz: original size in bytes
        unit: size unit to convert into

    Returns:
        Integer or float.
    >   br#  >   kb	kilobytesi   >   mb	megabytesi   >   gb	gigabytesi   @>   tb	terabytesl        z9`unit` must be one of {'b', 'kb', 'mb', 'gb', 'tb'}, got )r   )r  r  r   rq   rq   rr   scale_bytesR  s   

r  seriesSeries[Any]c                 C  s   ddl m} t| jj}t| j|r| j|jkr| jjj	d S | j|j
kr'dS | j|jkr/dS |  }t|r=|jjdkS t|rGt|jjS t|rO|jjS t|rW|jjS t|rjddlm} ||joi|jjS dS )a  Return whether indices of categories are semantically meaningful.

    This is a convenience function to accessing what would otherwise be
    the `is_ordered` property from the DataFrame Interchange Protocol,
    see https://data-apis.org/dataframe-protocol/latest/API.html.

    - For Polars:
      - Enums are always ordered.
      - Categoricals are ordered if `dtype.ordering == "physical"`.
    - For pandas-like APIs:
      - Categoricals are ordered if `dtype.cat.ordered == True`.
    - For PyArrow table:
      - Categoricals are ordered if `dtype.type.ordered == True`.

    Arguments:
        series: Input Series.

    Returns:
        Whether the Series is an ordered categorical.

    Examples:
        >>> import narwhals as nw
        >>> import pandas as pd
        >>> import polars as pl
        >>> data = ["x", "y"]
        >>> s_pd = pd.Series(data, dtype=pd.CategoricalDtype(ordered=True))
        >>> s_pl = pl.Series(data, dtype=pl.Categorical(ordering="physical"))

        Let's define a library-agnostic function:

        >>> @nw.narwhalify
        ... def func(s):
        ...     return nw.is_ordered_categorical(s)

        Then, we can pass any supported library to `func`:

        >>> func(s_pd)
        True
        >>> func(s_pl)
        True
    r   )InterchangeSeries
is_orderedTFphysical)is_dictionary)narwhals._interchange.seriesr  r  rU  r   r   dtypeCategoricalr   describe_categoricalr   r`  r-   orderingr,   r   catorderedr&   r%   r.   narwhals._arrow.utilsr  r	  )r  r  r   native_seriesr  rq   rq   rr   is_ordered_categoricalk  s.   *
r  n_bytesr   r   c                 C  s   d}t |dd t| |dS )Nz}Use `generate_temporary_column_name` instead. `generate_unique_token` is deprecated and it will be removed in future versions1.13.0r   )r  r   )issue_deprecation_warninggenerate_temporary_column_name)r  r   r   rq   rq   rr   generate_unique_token  s   r  c                 C  sD   d}	 t | }||vr|S |d7 }|dkr!d| d| }t|q)a  Generates a unique column name that is not present in the given list of columns.

    It relies on [python secrets token_hex](https://docs.python.org/3/library/secrets.html#secrets.token_hex)
    function to return a string nbytes random bytes.

    Arguments:
        n_bytes: The number of bytes to generate for the token.
        columns: The list of columns to check for uniqueness.

    Returns:
        A unique token that is not present in the given list of columns.

    Raises:
        AssertionError: If a unique token cannot be generated after 100 attempts.

    Examples:
        >>> import narwhals as nw
        >>> columns = ["abc", "xyz"]
        >>> nw.generate_temporary_column_name(n_bytes=8, columns=columns) not in columns
        True
    r   Tr   d   zMInternal Error: Narwhals was not able to generate a column name with n_bytes=z and not in )r
   r   )r  r   countertokenr   rq   rq   rr   r    s   r  compliant_frameIterable[str]strict	list[str]c                   sT   | j  t|}|r fdd|D }|rtj| d|S tt t|}|S )Nc                      g | ]}| vr|qS rq   rq   )r)  xcolsrq   rr   rH    rk  z)parse_columns_to_drop.<locals>.<listcomp>)missing_columnsavailable_columns)r   r  r/   'from_missing_and_available_column_namessetintersection)r  r   r  to_dropr  rq   r  rr   parse_columns_to_drop  s   r  sequenceSequence[_T] | AnyTypeIs[Sequence[_T]]c                 C  s   t | to
t | t S ry   )r   r   rj   )r  rq   rq   rr   is_sequence_but_not_str     r  TypeIs[_SliceNone]c                 C  s   t | to
| td kS ry   )r   slicer  rq   rq   rr   is_slice_none  r  r  $TypeIs[SizedMultiIndexSelector[Any]]c                 C  sf   t  }t| ot| dkrt| d tpt| dkp2t| o%|| j|jp2t	| s.t
| o2| j S r   )r   r  r  r   r&  r(   
issubdtyper  integerr'   is_compliant_series
is_integer)r  nprq   rq   rr   is_sized_multi_index_selector  s   $r  -TypeIs[Sequence[_T] | Series[Any] | _1DArray]c                 C  s    t | pt| pt| pt| S ry   )r  r(   r'   r  r  rq   rq   rr   is_sequence_like  s   r  TypeIs[_SliceIndex]c                 C  sB   t | to t | jtp t | jtp t | jto | jd u o | jd u S ry   )r   r  r|  r&  r}  r~  r  rq   rq   rr   is_slice_index  s   

r  TypeIs[range]c                 C  s
   t | tS ry   )r   ranger  rq   rq   rr   is_range     
r  TypeIs[SingleIndexSelector]c                 C  s   t t| tot| t  S ry   )r   r   r&  r  rq   rq   rr   is_single_index_selector#  s   r  5TypeIs[SingleIndexSelector | MultiIndexSelector[Any]]c                 C  s   t | pt| pt| S ry   )r  r  r  r  rq   rq   rr   is_index_selector'  s
   r  tpTypeIs[list[_T]]c                 C  s    t t| to| ot| d |S r   )r   r   r  )r  r  rq   rq   rr   
is_list_of/  s    r  c                  C  s   ddl } ddlm} ddl}t||jj}|  }d}z-|rE| |}|	|s7t
|jdd }r?|	dr?|j}|d7 }nW ~|S |s	 W ~|S ~w )zFind the first place in the stack that is not inside narwhals.

    Returns:
        Stacklevel.

    Taken from:
    https://github.com/pandas-dev/pandas/blob/ab89c53f48df67709a533b6a95ce3d911871a0a8/pandas/util/_exceptions.py#L30-L51
    r   N)Pathco_qualnamezsingledispatch.r   )inspectpathlibr  r  rj   __file__parentcurrentframegetfiler  rX  f_codef_back)r  r  nwpkg_dirframenfnamequalnamerq   rq   rr   find_stacklevel4  s0   	


r  messager   c                 C  s   t | tt d dS )zIssue a deprecation warning.

    Arguments:
        message: The message associated with the warning.
        _version: Narwhals version when the warning was introduced. Just used for internal
            bookkeeping.
    )r  category
stacklevelN)r   DeprecationWarningr  )r  r   rq   rq   rr   r  ^  s   r  bool | Noneri  pass_through_defaultemit_deprecation_warningc                C  sh   | d u r|d u r|}|S | d ur#|d u r#|rd}t |dd |  }|S | d u r.|d ur.	 |S d}t|)Nz`strict` in `from_native` is deprecated, please use `pass_through` instead.

Note: `strict` will remain available in `narwhals.stable.v1`.
See https://narwhals-dev.github.io/narwhals/backcompat/ for more information.
r  r  z,Cannot pass both `strict` and `pass_through`)r  r   )r  ri  r  r  r   rq   rq   rr   validate_strict_and_pass_thoughi  s   r  r%  F)warn_versionrequiredr  r  *Callable[[Callable[P, R]], Callable[P, R]]c                   s   d fdd}|S )a8  Decorator to transition from `native_namespace` to `backend` argument.

    Arguments:
        warn_version: Emit a deprecation warning from this version.
        required: Raise when both `native_namespace`, `backend` are `None`.

    Returns:
        Wrapped function, with `native_namespace` **removed**.
    fnCallable[P, R]rw   c                  s   t  d	 fdd}|S )
Nr  P.argskwdsP.kwargsrw   rg   c                    s   | dd }| dd }|d ur!|d u r!rd}t|d |}n#|d ur/|d ur/d}t||d u rD|d u rDrDd j d}t|||d<  | i |S )Nr   r   z`native_namespace` is deprecated, please use `backend` instead.

Note: `native_namespace` will remain available in `narwhals.stable.v1`.
See https://narwhals-dev.github.io/narwhals/backcompat/ for more information.
r  z0Can't pass both `native_namespace` and `backend`z `backend` must be specified in `z`.)popr  r   rm   )r  r  r   r   r   )r  r  r  rq   rr   wrapper  s    z=deprecate_native_namespace.<locals>.decorate.<locals>.wrapper)r  r  r  r  rw   rg   r   )r  r  r  r  r  rr   decorate  s   z,deprecate_native_namespace.<locals>.decorateN)r  r  rw   r  rq   )r  r  r  rq   r  rr   deprecate_native_namespace  s   r  window_sizemin_samples
int | Nonetuple[int, int]c                 C  s   | dk r
d}t |t| ts| jj}d| d}t||d urL|dk r+d}t |t|ts>|jj}d| d}t||| krHd}t|| |fS | }| |fS )Nr   z+window_size must be greater or equal than 1zargument 'window_size': 'z,' object cannot be interpreted as an integerz+min_samples must be greater or equal than 1zargument 'min_samples': 'z6`min_samples` must be less or equal than `window_size`)r   r   r&  	__class__rm   r
  r1   )r  r  r   _typerq   rq   rr   _validate_rolling_arguments  s.   



r  headernative_reprc              	   C  s|  zt  j}W n ty   tt dd}Y nw | }tdd |D }|d |krt|t| }dd|  d}|t|  }|d	d
|d   |  d
|d |d    d7 }|d	d|  d7 }|| d }|| d || d  }	|D ]}
|d	d
|  |
 d
|	| t|
   d7 }qw|dd|  d7 }|S dt|  }dd dd
|d   |  d
|d |d    dd d	S )NCOLUMNSP   c                 s  s    | ]}t |V  qd S ry   )r  )r)  linerq   rq   rr   r+    s    z generate_repr.<locals>.<genexpr>   u   ┌u   ─u   ┐
| z|
-u   └u   ┘'   uu   ───────────────────────────────────────u   ┐
|u/   |
| Use `.to_native` to see native output |
└)	osget_terminal_sizer   OSErrorr&  getenv
splitlinesmaxr  )r  r  terminal_widthnative_linesmax_native_widthlengthoutputheader_extrastart_extra	end_extrar	  diffrq   rq   rr   generate_repr  s<   0.
r  subsetSequence[str] | Nonec                 C  s>   |d urt ||  }rdt| d|  }t|d S d S )Nz
Column(s) z not found in )r  
differencesortedr/   )r   r  missingr   rq   rq   rr   check_column_exists  s   r$  c                 C  sl   t t| }t | |kr4ddlm} || }dd | D }ddd | D }d| }t|d S )	Nr   )Counterc                 S  s   i | ]\}}|d kr||qS r   rq   r)  kr*  rq   rq   rr   
<dictcomp>  s    z1check_column_names_are_unique.<locals>.<dictcomp>r%  c                 s  s&    | ]\}}d | d| dV  qdS )z
- 'z' z timesNrq   r&  rq   rq   rr   r+    s   $ z0check_column_names_are_unique.<locals>.<genexpr>z"Expected unique column names, got:)r  r  collectionsr%  rA  joinr0   )r   len_unique_columnsr%  r  
duplicatesr   rq   rq   rr   check_column_names_are_unique  s   
r-  	time_unit$TimeUnit | Iterable[TimeUnit] | None	time_zone7str | timezone | Iterable[str | timezone | None] | None%tuple[Set[TimeUnit], Set[str | None]]c                 C  sd   | d u rh dnt | tr| hnt| }|d u rd hnt |ttfr't|hndd |D }||fS )N>   smsnsusc                 S  s    h | ]}|d urt |nd qS ry   )rj   )r)  tzrq   rq   rr   	<setcomp>  s     z1_parse_time_unit_and_time_zone.<locals>.<setcomp>)r   rj   r  r   )r.  r0  
time_units
time_zonesrq   rq   rr   _parse_time_unit_and_time_zone   s   	r;  r  rL   r   r9  Set[TimeUnit]r:  Set[str | None]c                 C  s2   t | |jo| j|v o| j|v pd|v o| jd uS )N*)r   Datetimer.  r0  )r  r   r9  r:  rq   rq   rr   %dtype_matches_time_unit_and_time_zone  s   
r@  r  c                C  s   | j S ry   r   )r  rq   rq   rr   get_column_names"  s   rB  namesContainer[str]c                   s    fdd| j D S )Nc                   r  rq   rq   )r)  col_namerC  rq   rr   rH  '  rk  z(exclude_column_names.<locals>.<listcomp>rA  )r  rC  rq   rF  rr   exclude_column_names&  s   rG  EvalNames[Any]c                  s   d fdd}|S )N_framer   rw   r   c                  s    S ry   rq   )rI  rF  rq   rr   r  +  r   z$passthrough_column_names.<locals>.fn)rI  r   rw   r   rq   )rC  r  rq   rF  rr   passthrough_column_names*  s   rJ  attrc                 C  s   t  }t| |||uS ry   )objectr	   )r  rK  sentinelrq   rq   rr   r  1  s   r  KCompliantDataFrame[CompliantSeriesT, CompliantExprT, NativeFrameT_co] | AnyMTypeIs[CompliantDataFrame[CompliantSeriesT, CompliantExprT, NativeFrameT_co]]c                 C  
   t | dS )N__narwhals_dataframe__r  r  rq   rq   rr   is_compliant_dataframe6     
rS  9CompliantLazyFrame[CompliantExprT, NativeFrameT_co] | Any;TypeIs[CompliantLazyFrame[CompliantExprT, NativeFrameT_co]]c                 C  rP  )N__narwhals_lazyframe__rR  r  rq   rq   rr   is_compliant_lazyframe<  rT  rX  'CompliantSeries[NativeSeriesT_co] | Any)TypeIs[CompliantSeries[NativeSeriesT_co]]c                 C  rP  )N__narwhals_series__rR  r  rq   rq   rr   r  B  rT  r  ECompliantExpr[CompliantFrameT, CompliantSeriesOrNativeExprT_co] | AnyGTypeIs[CompliantExpr[CompliantFrameT, CompliantSeriesOrNativeExprT_co]]c                 C  rP  )N__narwhals_expr__hasattrr  rq   rq   rr   is_compliant_exprH  rT  ra  "TypeIs[EagerAllowedImplementation]c                 C  s   | t jt jt jt jt jhv S ry   )r}   r   r   r   r   r   r  rq   rq   rr   is_eager_allowedN  s   rc  TypeIs[SupportsNativeNamespace]c                 C  rP  )Nrs  r_  r  rq   rq   rr   has_native_namespaceX  r  re  TypeIs[DataFrameLike]c                 C  rP  )N__dataframe__r_  r  rq   rq   rr   _supports_dataframe_interchange\  r  rh  TypeIs[ArrowStreamExportable]c                 C  rP  )N__arrow_c_stream__rR  r  rq   rq   rr   supports_arrow_c_stream`  r  rk  left_onright_ondict[str, str]c                   s"    fdd|D }t t||S )aO  Remap join keys to avoid collisions.

    If left keys collide with the right keys, append the suffix.
    If there's no collision, let the right keys be.

    Arguments:
        left_on: Left keys.
        right_on: Right keys.
        suffix: Suffix to append to right keys.

    Returns:
        A map of old to new right keys.
    c                 3  s(    | ]}| v r|  n|V  qd S ry   rq   )r)  keyrl  r  rq   rr   r+  t  s    
z(_remap_full_join_keys.<locals>.<genexpr>)dictzip)rl  rm  r  right_keys_suffixedrq   rp  rr   _remap_full_join_keysd  s   rt  datarF   contextpa.Tablec                C  s^   t dr"ddl}ddlm} |j}|t||d}|jj| |djS dt	| j
d}t|)	zGuards `ArrowDataFrame.from_arrow` w/ safer imports.

    Arguments:
        data: Object which implements `__arrow_c_stream__`.
        context: Initialized compliant object.

    Returns:
        A PyArrow Table.
    r   r   N)ArrowNamespace)r   r   )rv  z@PyArrow>=14.0.0 is required for `from_arrow` for object of type r,  )r   r   narwhals._arrow.namespacerx  r   r   
_dataframe
from_arrowr   r	  rm   ModuleNotFoundError)ru  rv  r   rx  r   r5  r   rq   rq   rr   _into_arrow_tablez  s   
r}  r  c                C     | S )a  Visual-only marker for unstable functionality.

    Arguments:
        fn: Function to decorate.

    Returns:
        Decorated function (unchanged).

    Examples:
        >>> from narwhals.utils import unstable
        >>> @unstable
        ... def a_work_in_progress_feature(*args):
        ...     return args
        >>>
        >>> a_work_in_progress_feature.__name__
        'a_work_in_progress_feature'
        >>> a_work_in_progress_feature(1, 2, 3)
        (1, 2, 3)
    rq   r  rq   rq   rr   unstable  s   r  )r      
deprecatedCallable[[_Fn], _Fn]c                C  s   ddd}|S )Nfuncre   rw   c                S  r~  ry   rq   )r  rq   rq   rr   r    r   zdeprecated.<locals>.wrapper)r  re   rw   re   rq   )r  r  rq   rq   rr   r    s   
r  c                   @  sV   e Zd ZdZd d!ddZd"d
dZd#ddZ	d d$ddZd%ddZe	d&ddZ
dS )'not_implementeda  Mark some functionality as unsupported.

    Arguments:
        alias: optional name used instead of the data model hook [`__set_name__`].

    Returns:
        An exception-raising [descriptor].

    Notes:
        - Attribute/method name *doesn't* need to be declared twice
        - Allows different behavior when looked up on the class vs instance
        - Allows us to use `isinstance(...)` instead of monkeypatching an attribute to the function

    Examples:
        >>> from narwhals.utils import not_implemented
        >>> class Thing:
        ...     def totally_ready(self) -> str:
        ...         return "I'm ready!"
        ...
        ...     not_ready_yet = not_implemented()
        >>>
        >>> thing = Thing()
        >>> thing.totally_ready()
        "I'm ready!"
        >>> thing.not_ready_yet()
        Traceback (most recent call last):
            ...
        NotImplementedError: 'not_ready_yet' is not implemented for: 'Thing'.
        ...
        >>> isinstance(Thing.not_ready_yet, not_implemented)
        True

    [`__set_name__`]: https://docs.python.org/3/reference/datamodel.html#object.__set_name__
    [descriptor]: https://docs.python.org/3/howto/descriptor.html
    Nalias
str | Nonerw   r   c                C  s
   || _ d S ry   )r   )rz   r  rq   rq   rr   __init__  rT  znot_implemented.__init__rj   c                 C  s    dt | j d| j d| j S )N<z>: r,  )r	  rm   _name_owner_namer   rq   rq   rr   __repr__  s    znot_implemented.__repr__ru   r1  namec                 C  s   |j | _| jp|| _d S ry   )rm   r  r   r  )rz   ru   r  rq   rq   rr   __set_name__  s   znot_implemented.__set_name__rt   _T | Literal['raise'] | Nonetype[_T] | Noner   c                C  s&   |d u r| S t |d| j}t| j|)Nr~   )rX  r  _not_implemented_errorr  )rz   rt   ru   whorq   rq   rr   r{     s   znot_implemented.__get__r  r  c                 O  s
   |  dS )Nraise)r{   )rz   r  r  rq   rq   rr   __call__  rT  znot_implemented.__call__r  r5   r7   c                C  s   |  }t ||S )a  Alt constructor, wraps with `@deprecated`.

        Arguments:
            message: **Static-only** deprecation message, emitted in an IDE.

        Returns:
            An exception-raising [descriptor].

        [descriptor]: https://docs.python.org/3/howto/descriptor.html
        r  )r   r  r  rq   rq   rr   r     s   znot_implemented.deprecatedry   )r  r  rw   r   )rw   rj   )ru   r1  r  rj   rw   r   )rt   r  ru   r  rw   r   )r  r   r  r   rw   r   )r  r5   rw   r7   )rm   rn   ro   r   r  r  r  r{   r  r   r  rq   rq   rq   rr   r    s    $


r  whatr  NotImplementedErrorc                C  s   | d|d}t |S )Nz is not implemented for: z.

If you would like to see this functionality in `narwhals`, please open an issue at: https://github.com/narwhals-dev/narwhals/issues)r  )r  r  r   rq   rq   rr   r    s   r  c                   @  sT   e Zd ZU dZded< ded< eddddZedddZdddZ	dddZ
dS )requiresa"  Method decorator for raising under certain constraints.

    Attributes:
        _min_version: Minimum backend version.
        _hint: Optional suggested alternative.

    Examples:
        >>> from narwhals.utils import requires, Implementation
        >>> class SomeBackend:
        ...     _implementation = Implementation.PYARROW
        ...     _backend_version = 20, 0, 0
        ...
        ...     @requires.backend_version((9000, 0, 0))
        ...     def really_complex_feature(self) -> str:
        ...         return "hello"
        >>> backend = SomeBackend()
        >>> backend.really_complex_feature()
        Traceback (most recent call last):
            ...
        NotImplementedError: `really_complex_feature` is only available in PyArrow>='9000.0.0', found version '20.0.0'.
    r   _min_versionrj   _hintr%  hintminimumrw   r7   c                C  s   |  | }||_||_|S )zMethod decorator for raising below a minimum `_backend_version`.

        Arguments:
            minimum: Minimum backend version.
            hint: Optional suggested alternative.

        Returns:
            An exception-raising decorator.
        )__new__r  r  )r   r  r  r  rq   rq   rr   r   3  s   
zrequires.backend_versionr   c                C  s   d dd | D S )Nr,  c                 s  s    | ]}| V  qd S ry   rq   )r)  drq   rq   rr   r+  E  s    z,requires._unparse_version.<locals>.<genexpr>)r*  )r   rq   rq   rr   _unparse_versionC  s   zrequires._unparse_versionrt   r   r   c             	   C  sr   |j | jkrd S | j}|jj}| | j}| |j }d| d| d|d|d	}| jr5| d| j }t|)N`z` is only available in z>=z, found version r,  
)r   r  _wrapped_namer~   r   r  r  r  )rz   rt   methodr   r  foundr   rq   rq   rr   _ensure_versionG  s   zrequires._ensure_versionr  _Method[_ContextT, P, R]c                  s$    j _t d fd	d
}|S )Nrt   r   r  r  r  r  rw   rg   c                   s     |   | g|R i |S ry   )r  )rt   r  r  r  rz   rq   rr   r  V  s   
z"requires.__call__.<locals>.wrapper)rt   r   r  r  r  r  rw   rg   )rm   r  r   )rz   r  r  rq   r  rr   r  S  s   zrequires.__call__N)r%  )r  rj   r  r   rw   r7   )r   r   rw   rj   )rt   r   rw   r   )r  r  rw   r  )rm   rn   ro   r   rp   r   r   staticmethodr  r  r  rq   rq   rq   rr   r    s   
 
r  	str_slicer]   "tuple[int | None, int | None, Any]c                 C  sH   | j d ur|| j nd }| jd ur|| jd nd }| j}|||fS )Nr   )r|  rQ  r}  r~  )r  r   r|  r}  r~  rq   rq   rr   convert_str_slice_to_int_slice_  s   
r  )r   r}   r   r   rw   r   )r   r   rw   rS   )r  r  rw   r   )r   r  rw   r  )r  rj   r  rj   rw   rj   )r  rj   r  rj   rw   rj   )r  r   rw   r  )r  r   rw   r   )r  r   rw   r   )r   r$  rw   r   )r/  r	  r0  r1  rw   r2  )r/  r5  r0  r1  rw   r6  )r/  r	  r0  r7  rw   r8  )r/  r5  r0  r7  rw   r9  )r/  r	  r0  r:  rw   r;  )r/  r5  r0  r:  rw   r<  )r/  r   r0  r=  rw   r>  )r/  r   r0  r   rw   r   )rA  rB  rw   r   )rL  r_   rM  rN  rw   r_   )r  r_  rw   rv   ry   )r  r_   rd  re  rQ  rf  rw   r_   )r  r_   rw   r_   )r  r   r   r   rw   rw  )rz  r{  r   r   rw   r   )r  r_   r  r   r  r  rw   r_   )r  r&  r  rX   rw   r  )r  r  rw   r   )r  r&  r   r   rw   rj   )r  r   r   r  r  r   rw   r  )r  r  rw   r  )r  r   rw   r  )r  r   rw   r  )r  r  rw   r  )r  r   rw   r  )r  r   rw   r  )r  r   rw   r  )r  r   rw   r  )r  r   r  r1  rw   r  )rw   r&  )r  rj   r   rj   rw   r   )
r  r  ri  r  r  r   r  r   rw   r   )r  rj   r  r   rw   r  )r  r&  r  r   rw   r  )r  rj   r  rj   rw   rj   )r   r   r  r   rw   r   )r   r   rw   r   )r.  r/  r0  r1  rw   r2  )
r  rL   r   rS   r9  r<  r:  r=  rw   r   )r  r   rw   r   )r  r   rC  rD  rw   r   )rC  r   rw   rH  )r  r   rK  rj   rw   r   )r  rN  rw   rO  )r  rU  rw   rV  )r  rY  rw   rZ  )r  r\  rw   r]  )r  r}   rw   rb  )r  r   rw   rd  )r  r   rw   rf  )r  r   rw   ri  )rl  r   rm  r   r  rj   rw   rn  )ru  rF   rv  r   rw   rw  )r  re   rw   re   )r  rj   rw   r  )r  rj   r  rj   rw   r  )r  r]   r   r   rw   r  )
__future__r   r  r'  datetimer   enumr   r   	functoolsr   importlib.utilr   r  r	   secretsr
   typingr   r   r   r   r   r   r   r   r   r   r   r   warningsr   narwhals.dependenciesr   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   narwhals.exceptionsr/   r0   r1   typesr2   r3   Setr   r   r   r   typing_extensionsr4   r5   r6   r7   r8   r9   narwhals._compliantr:   r;   r<   r=   r>   r?   r@   narwhals._compliant.typingrA   r  rB   rD   narwhals._translaterE   rF   rI  rH   rJ   r?  rL   r!  rN   narwhals.typingrO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   ra   rb   rc   rd   re   rf   rg   ri   rs   r|   r   r   r   r   r   r   r   r   r   rp   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r   r4  rK  r^  rc  rq  rv  ry  rt  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r$  r-  r;  r@  rB  rG  rJ  r  rS  rX  r  ra  rc  re  rh  rk  rt  r}  r  sysversion_infor  r  r  r  r  rq   rq   rq   rr   <module>   s      	
_&[25H%*)$
T	F