
    gD                       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' e
rSd d!l(m)Z) d dl*Z+d d"l,m-Z- d d#l,m.Z. d d$l/m0Z0 d d%l/m1Z1 d d&l2m3Z3 d d'l4m5Z5 d d(l4m6Z6 d d)l4m7Z7  ed*ee1e   e0e   e3e   f   +      Z8 G d, d-e      Z9 G d. d/e      Z:e:jv                  d0e:jx                  d0e:jz                  d1e:j|                  d2e:j~                  d3e:j                  d4e:j                  d5e:j                  d6e:j                  d7i	ZDd8eEd9<   	 	 	 	 	 	 dVd:ZFdWd;ZGdXd<ZHdYd=ZIdZd>ZJd[d?ZKd\d@ZLd]dAZMd^dBZNd_dCZO	 	 	 	 	 	 d`dDZPdadEZQ	 dbddF	 	 	 	 	 	 	 dcdGZRdddHZS	 	 	 	 	 	 dedIZT	 	 	 	 	 	 	 	 dfdJZUdgdKZVdhdLZWdidMZXdidNZY	 	 	 	 	 	 	 	 djdOZZdkdPZ[dldQZ\dmdRZ]	 	 	 	 	 	 	 	 	 	 dndSZ^	 	 	 	 	 	 dodTZ_dpdUZ`y)q    )annotationsN)Enum)auto)	token_hex)TYPE_CHECKING)Any)Iterable)Sequence)TypeVar)Union)cast)warn)get_cudf)get_dask_dataframe)
get_duckdb)get_ibis)	get_modin)
get_pandas)
get_polars)get_pyarrow)get_pyspark_sql)is_cudf_series)is_modin_series)is_pandas_dataframe)is_pandas_like_dataframe)is_pandas_like_series)is_pandas_series)is_polars_series)is_pyarrow_chunked_array)ColumnNotFoundError)InvalidOperationError)
ModuleType)Self)	TypeGuard	DataFrame	LazyFrameSeries)DTypes)IntoSeriesT)SizeUnitFrameOrSeriesT)boundc                  (    e Zd Z e       Z e       Zy)VersionN)__name__
__module____qualname__r   V1MAIN     C/var/www/openai/venv/lib/python3.12/site-packages/narwhals/utils.pyr1   r1   8   s    	B6Dr8   r1   c                  &   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	 	 	 	 	 	 dd       ZddZddZddZddZddZddZdd	Zdd
ZddZddZddZy)Implementationz?Implementation of native object (pandas, Polars, PyArrow, ...).c                   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	}|j'                  |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   IBISgetUNKNOWN)clsnative_namespacemappings      r9   from_native_namespacez$Implementation.from_native_namespaceV   s     L.//K--J++M>11~55L.// ."5"5L.//J++

 {{+^-C-CDDr8   c                `   t         j                  t               t         j                  t	               t         j
                  t               t         j                  t               t         j                  t               t         j                  t               t         j                  t               i}||    S )zyReturn the native namespace module corresponding to Implementation.

        Returns:
            Native module.
        )r;   r=   r   r>   r   r?   r   r@   r   rA   r   rB   r   rC   r   )selfrJ   s     r9   to_native_namespacez"Implementation.to_native_namespaceo   su     !!:<  )+""KM""O$5!!:<!3!5
 t}r8   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=   rM   s    r9   	is_pandaszImplementation.is_pandas        ~,,,,r8   c                d    | 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?   rP   s    r9   is_pandas_likezImplementation.is_pandas_like   s(     --~/C/C^EXEXYYYr8   c                &    | t         j                  u S )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;   rB   rP   s    r9   	is_polarszImplementation.is_polars   rR   r8   c                &    | t         j                  u S )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?   rP   s    r9   is_cudfzImplementation.is_cudf        ~****r8   c                &    | t         j                  u S )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>   rP   s    r9   is_modinzImplementation.is_modin   s     ~++++r8   c                &    | t         j                  u S )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;   rA   rP   s    r9   
is_pysparkzImplementation.is_pyspark        ~----r8   c                &    | t         j                  u S )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@   rP   s    r9   
is_pyarrowzImplementation.is_pyarrow   r^   r8   c                &    | t         j                  u S )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;   rC   rP   s    r9   is_daskzImplementation.is_dask   rY   r8   c                &    | t         j                  u S )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;   rD   rP   s    r9   	is_duckdbzImplementation.is_duckdb   rR   r8   c                &    | t         j                  u S )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;   rE   rP   s    r9   is_ibiszImplementation.is_ibis  rY   r8   N)rH   z
type[Self]rI   r"   returnr;   )rM   r#   rg   r"   )rg   bool)r2   r3   r4   __doc__r   r=   r>   r?   r@   rA   rB   rC   rD   rE   rG   classmethodrK   rN   rQ   rT   rV   rX   r[   r]   r`   rb   rd   rf   r7   r8   r9   r;   r;   =   s    IVF FE6DfG!fG!VF 6DVF 6DfG!EE+5E	E E0"- Z - + , . . + - +r8   r;   )r         )   
   )   )rl   rl   )r      rl   )i     )   )   z%dict[Implementation, tuple[int, ...]]MIN_VERSIONSc                L    |t         |    x}k  rd|  d| d| }t        |      y )NzMinimum version of z supported by Narwhals is z	, found: )rt   
ValueError)implementationbackend_versionmin_versionmsgs       r9   validate_backend_versionr{   .  sC     n)EE+F#N#33Mk]Zcdsctuo Gr8   c                    | t         j                  u rddlm} |S | t         j                  u rddlm} |S d|  }t        |      )Nr   )dtypeszCongratulations, you have entered unreachable code.
Please report an issue at https://github.com/narwhals-dev/narwhals/issues.
Version: )r1   r5   narwhals.stable.v1r}   r6   narwhalsAssertionError)versionr}   rz   s      r9   import_dtypes_moduler   6  sQ    '**- M 
GLL	 # My" 	
 S!!r8   c                D    | j                  |      r| t        |      d  S | S N)
startswithlen)textprefixs     r9   remove_prefixr   E  s$    vCKM""Kr8   c                F    | j                  |      r| d t        |        S | S r   )endswithr   )r   suffixs     r9   remove_suffixr   K  s&    }}VNs6{l##Kr8   c                P    | sg S t        |       dk(  rt        | d         r| d   S | S )Nrr   r   )r   _is_iterable)argss    r9   flattenr   Q  s.    	
4yA~,tAw/AwKr8   c                8    t        | t        t        f      s| fS | S r   )
isinstancelisttuple)args    r9   tupleifyr   Y  s    cD%=)vJr8   c                ~   ddl m} t        |       st        |       rdt	        |        d}t        |      t               x}Rt        | |j                  |j                  |j                  |j                  f      rdt	        |        d}t        |      t        | t              xr t        | t        t        |f       S )Nr   r)   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.seriesr*   r   r   type	TypeErrorr   r   Exprr&   r(   r	   strbytes)r   r*   rz   pls       r9   r   r   _  s    &3#3C#88cCuvnl'Jbii",,=- 7tCyk B3 3 	 nc8$RZc5&=Q-R)RRr8   c                h    t        | t              r| j                  d      } t        d | D              S )zSimple version parser; split into a tuple of ints for comparison.

    Arguments:
        version: Version string to parse.

    Returns:
        Parsed version number.
    .c           
   3  n   K   | ]-  }t        t        j                  d dt        |                   / yw)z\D N)intresubr   ).0vs     r9   	<genexpr>z parse_version.<locals>.<genexpr>  s'     AARVVE2s1v./s   35)r   r   splitr   )r   s    r9   parse_versionr   s  s-     '3--$AAAAr8   c                    ddl m} t        | |      rt        | |      S t        | |      xs t        | t              xr t	        | |      S )Nr   )DType)narwhals.dtypesr   r   r   
issubclass)objrH   r   s      r9   isinstance_or_issubclassr     sA    %#u#s##c3SJsD$9$Rjc>RSr8   c                    ddl m ddl m t        fd| D              st        fd| D              ry d| D cg c]  }t	        |       c} }t        |      c c}w )Nr   r%   r'   c              3  6   K   | ]  }t        |        y wr   r   )r   itemr&   s     r9   r   z$validate_laziness.<locals>.<genexpr>  s     
954:dI&5   c              3  6   K   | ]  }t        |        y wr   r   )r   r   r(   s     r9   r   z$validate_laziness.<locals>.<genexpr>  s     :EDJtY'Er   zGThe items to concatenate should either all be eager, or all lazy, got: )narwhals.dataframer&   r(   allr   r   )itemsr   rz   r&   r(   s      @@r9   validate_lazinessr     s`    ,,

95
99:E::SlqTrlqdhUYZ^U_lqTrSs
tC
C. Uss   Ac                   ddl m} ddlm} d
d}t	        t
        |       }t	        t
        |      }t        t        |dd      |      rt        t        |dd      |      r ||j                  j                  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                  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                  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                  j                  j                                 S t%        |      t%        |      k7  r%d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)PandasLikeSeriesc                6    | j                   sd}t        |      y )Nz'given index doesn't have a unique index)	is_uniquerv   )indexrz   s     r9   _validate_indexz*maybe_align_index.<locals>._validate_index  s    ;CS/! r8   _compliant_frameN_compliant_seriesz6Expected `lhs` and `rhs` to have the same length, got z and )r   r   rg   None)narwhals._pandas_like.dataframer   narwhals._pandas_like.seriesr   r   r   r   getattrr   _native_framer   _from_compliant_dataframe_from_native_framelocr   _native_series_from_compliant_series_from_native_seriesr   rv   )lhsrhsr   r   r   lhs_anyrhs_anyrz   s           r9   maybe_align_indexr     sK   B D="
 3nG3nG+T24G
WW&8$?AT
U00>>DDE00>>DDE00$$77((66::,,::@@
 	
 +T24G
WW&94@BR
S00>>DDE11@@FFG00$$77((66::--<<BB
 	
 ,d35E
WW&8$?AT
U11@@FFG00>>DDE--%%99))88<<,,::@@
 	
 ,d35E
WW&94@BR
S11@@FFG11@@FFG--%%99))88<<--<<BB
 	
 7|s7|#Fs7|nTYZ]^eZfYghoJr8   c                    t        t        |       }|j                         }t        |      st	        |      r|j
                  S y)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)
    N)r   r   	to_nativer   r   r   )r   obj_any
native_objs      r9   maybe_get_indexr     s<    : 3nG""$J
+/DZ/Pr8   )r   c                  ddl m} t        t        |       }|j                         }||d}t	        |      |s|sd}t	        |      |.t        |      r|D cg c]  } ||d       c}n	 ||d      }n|}t        |      r9|j                  |j                  j                  |j                  |                  S t        |      rsddlm
}	 |rd}t	        |       |	||| j                  j                  | j                  j                  	      }|j!                  |j                  j#                  |            S |S c c}w )
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   z8Only one of `column_names` or `index` should be providedz3Either `column_names` or `index` should be providedT)pass_through)	set_indexz/Cannot set index using column names on a Series)rw   rx   )narwhals.translater   r   r   rv   r   r   r   r   r   r   r   narwhals._pandas_like.utilsr   _implementation_backend_versionr   r   )
r   column_namesr   r   df_anyr   rz   idxkeysr   s
             r9   maybe_set_indexr     sN   ^ -#s^F!!#JE$5HoCo E" ;@@%3Ys.%@5t4 	 
+//##66z7K7KD7QR
 	
 
z	*9CCS/!00@@11BB	

 ,,$$88D
 	
 9 As   D?c                   t        t        |       }|j                         }t        |      rX|j	                         }t        ||      r|S |j                  |j                  j                  |j                  d                  S t        |      rX|j	                         }t        ||      r|S |j                  |j                  j                  |j                  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)
    T)drop)r   r   r   r   __native_namespace___has_default_indexr   r   r   reset_indexr   r   r   r   )r   r   r   rI   s       r9   maybe_reset_indexr   x  s    > 3nG""$J
+"779j*:;N00$$77
8N8NTX8N8YZ
 	
 Z("779j*:;N--%%99&&D&1
 	

 Nr8   c                    | j                   }t        ||j                        xr: |j                  dk(  xr) |j                  t        |      k(  xr |j                  dk(  S )Nr   rr   )r   r   
RangeIndexstartstopr   step)native_frame_or_seriesrI   r   s      r9   r   r     s]     #((E5*556 	KK1	JJ#e*$	 JJ!O	r8   c           	     Z   t        t        |       }|j                         }t        |      r:|j	                  |j
                  j                   |j                  |i |            S t        |      r:|j                  |j                  j                   |j                  |i |            S |S )a9  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   r   r   r   convert_dtypesr   r   r   r   )r   r   kwargsr   r   s        r9   maybe_convert_dtypesr     s    D 3nG""$J
+00$$77)
))4:6:
 	

 Z(--%%99)
))4:6:
 	

 Nr8   c                v    |dv r| S |dv r| dz  S |dv r| dz  S |dv r| dz  S |dv r| d	z  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 )rv   )szunitrz   s      r9   scale_bytesr    ss     ~		$	$Dy	$	$G|	$	$G|	$	$G|KD8Tor8   c                   ddl m} t        | j                  j                        }t        | j                  |      r<| j                  |j                  k(  r#| j                  j                  j                  d   S | j                  |j                  k(  ry| j                  |j                  k7  ry| j                         }t        |      r|j                  j                  dk(  S t        |      r|j                  j                   S t#        |      r|j                  j                   S t%        |      r|j                  j                   S t'        |      r|j(                  j                   S y)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)narwhals._interchange.seriesr  r   r   _versionr   dtypeCategoricalr   describe_categoricalr   r   r   orderingr   catorderedr   r   r   r   )seriesr  r}   native_seriess       r9   is_ordered_categoricalr    s'   T ?!&":":"C"CDF 	6++->?LLF...''66KK
 	
 ||v{{"||v)))$$&M&""++z99&  (((}%  (((m$  (((.!!)))r8   c                :    d}t        |d       t        | |      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  )n_bytescolumns)issue_deprecation_warninggenerate_temporary_column_name)r  r  rz   s      r9   generate_unique_tokenr  L  s%    	?  cH5)'7KKr8   c                f    d}	 t        |       }||vr|S |dz  }|dkD  rd| d| }t        |      /)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   rr   d   zMInternal Error: Narwhals was not able to generate a column name with n_bytes=z and not in )r   r   )r  r  countertokenrz   s        r9   r  r  U  s_    , G
'"L1S=*L	3  !%% r8   c                    | j                   }t        |      }|r/|D cg c]	  }||vs| }}|rt        j                  ||      |S t        t	        |      j                  t	        |                  }|S c c}w )N)missing_columnsavailable_columns)r  r   r    'from_missing_and_available_column_namessetintersection)compliant_framer  strictcolsto_dropxr  s          r9   parse_columns_to_dropr)  z  s    
 ""D7mG&-?g$1g?%MM /4 
 N s4y--c'l;<N @s
   	A7A7c                H    t        | t              xr t        | t               S r   )r   r
   r   )sequences    r9   is_sequence_but_not_strr,    s    h)K*Xs2K.KKr8   c                 p   ddl } ddlm} ddl}t	         ||j
                        j                        }| j                         }d}	 |re| j                  |      }|j                  |      s*t        |j                  dd      x}r#|j                  d      r|j                  }|dz  }n	 ~|S |re	 ~|S # ~w xY 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.rr   )inspectpathlibr.  r   r   __file__parentcurrentframegetfiler   r   f_codef_back)r0  r.  nwpkg_dirframenfnamequalnames           r9   find_stacklevelr>    s     $r{{#**+G   "E	AOOE*E($U\\=$GGG''(9:Q H'   H s   A B2 +B2 2B5c                8    t        | t        t                      y)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.
    )messagecategory
stacklevelN)r   DeprecationWarningr>  )r@  r  s     r9   r  r    s     	#5/BSTr8   c               n    | ||}|S | ||rd}t        |d       |  }|S | |	 |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 [stable api](../backcompat.md/) for more information.
r  r  z,Cannot pass both `strict` and `pass_through`)r  rv   )r%  r   pass_through_defaultemit_deprecation_warningrz   s        r9   validate_strict_and_pass_thoughrG    sy     ~,.+  
	 4#N 
 &cH=!z  
L4  =or8   c                b   | dk  rd}t        |      t        | t              s'| j                  j                  }d| d}t        |      |_|dk  rd}t        |      t        |t              s'|j                  j                  }d| d}t        |      || kD  rd}t        |      | |fS | }| |fS )Nrr   z+window_size must be greater or equal than 1zargument 'window_size': 'z,' object cannot be interpreted as an integerz+min_periods must be greater or equal than 1zargument 'min_periods': 'z6`min_periods` must be less or equal than `window_size`)rv   r   r   	__class__r2   r   r!   )window_sizemin_periodsrz   _types       r9   _validate_rolling_argumentsrM    s     Q;ok3'%%..'w /( ( 	 n??CS/!+s+))22E+E7 3, ,  C. $JC',, ## "##r8   c           
     f   	 t        j                         j                  }|j	                         }t        d |D              }|dz   |k  rt        |t        |             }dd|z   d}|t        |       z
  }|dd|dz  z   |  d|dz  |dz  z   z   d	z  }|dd
|z   d	z  }||z
  dz  }||z
  dz  ||z
  dz  z   }	|D ]$  }
|dd|z   |
 d|	|z   t        |
      z
  z   d	z  }& |dd|z   dz  }|S dt        |       z
  }dd dd|dz  z   |  d|dz  |dz  z   z   dd d	S # t        $ r d}Y w xY w)NP   c              3  2   K   | ]  }t        |        y wr   )r   )r   lines     r9   r   z generate_repr.<locals>.<genexpr>	  s     >3t9s      u   ┌u   ─u   ┐
| z|
-u   └u   ┘'   uu   ───────────────────────────────────────u   ┐
|u/   |
| Use `.to_native` to see native output |
└)osget_terminal_sizer  OSError
splitlinesmaxr   )headernative_reprterminal_widthnative_linesmax_native_widthlengthoutputheader_extrastart_extra	end_extrarQ  diffs               r9   generate_reprrg    s   --/77 ))+L>>>!n,%s6{3uV|nE*F+\1_%&vhsL!OlSTn4T/U.VVYZ	
 	Ac6l^3'' 00Q6..14AQ8QUV7VV	 D#{+,TF3	DT8TWZ[_W`8`3a2bbeffF !C's++FD
l^ qM?6(3aQ#7"8 99,c	+  s   D! !D0/D0)rw   r;   rx   tuple[int, ...]rg   r   )r   r1   rg   r+   )r   r   r   r   rg   r   )r   r   r   r   rg   r   )r   r   rg   z	list[Any])r   r   rg   r   )r   zAny | Iterable[Any]rg   rh   )r   zSequence[str | int]rg   rh  )r   r   rH   r   rg   rh   )r   zIterable[Any]rg   r   )r   r.   r   z-Series[Any] | DataFrame[Any] | LazyFrame[Any]rg   r.   )r   z-DataFrame[Any] | LazyFrame[Any] | Series[Any]rg   z
Any | Noner   )r   r.   r   zstr | list[str] | Noner   z6Series[IntoSeriesT] | list[Series[IntoSeriesT]] | Nonerg   r.   )r   r.   rg   r.   )r   zpd.Series | pd.DataFramerI   r   rg   rh   )r   r.   r   rh   r   z
bool | strrg   r.   )r   r   r  r-   rg   zint | float)r  zSeries[Any]rg   rh   )r  r   r  	list[str]rg   r   )r$  r   r  zIterable[str]r%  rh   rg   ri  )r+  r   rg   zTypeGuard[Sequence[Any]])rg   r   )r@  r   r  r   rg   r   )
r%  bool | Noner   rj  rE  rh   rF  rh   rg   rh   )rJ  r   rK  z
int | Nonerg   ztuple[int, int])r\  r   r]  r   rg   r   )a
__future__r   rW  r   enumr   r   secretsr   typingr   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   narwhals.exceptionsr    r!   typesr"   pandaspdtyping_extensionsr#   r$   r   r&   r(   r   r*   narwhals.typingr+   r,   r-   r.   r1   r;   r=   r>   r?   r@   rA   rB   rC   rD   rE   rt   __annotations__r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r)  r,  r>  r  rG  rM  rg  r7   r8   r9   <module>rx     s   " 	 	             * 4 , * + , , - 1 0 1 5 : 7 2 2 : 3 5 &+,,&&+(ininfSk&Q RN
d 
a+T a+J :*EF:4
73 
"5D	S(BT	^	^K^^B!L ,0Z EI	Z	Z(Z B	Z
 Zz1h	4	HK			0	0 $00:00f2EPL"&J  	$L'TU 	
 # 
4!$!$#-!$!$Hr8   