
    Lpj=                       % S r SSKJr  SSKrSSKJrJrJrJr  SSK	J
r
JrJrJrJr  SSKJrJrJrJrJrJrJrJrJrJrJrJr  \
(       aD  SSK	Jr  SSKrSSKrSSK r!SSK"r#SSK$J%r&  SS	K'J(r(J)r)  \&\\\\\4   r*\" S
5      r+Sr,S\-S'   \r.S\-S'   / SQr/ " S S\5      r0 " S S\\0\5      r1 " S S\0\5      r2 " S S\\\   \5      r3 " S S\\5      r4 " S S\1\4\5      r5 " S S\3\4\5      r6 " S S\2\5      r7 " S  S!\5\5      r8 " S" S#\6\5      r9 " S$ S%\0\5      r: " S& S'\5\5      r; " S( S)\6\5      r< " S* S+\2\5      r=S,r>S\-S-'   S.r?S\-S/'   S0r@S\-S1'   S2rAS\-S3'   S4rBS\-S5'   S6rCS\-S7'   S8rDS\-S9'   S:rES\-S;'   S<rFS\-S='   S>rGS\-S?'   \=rHS\-S@'   \=rIS\-SA'   SBrJS\-SC'   SDrKS\-SE'   SFrLS\-SG'   SHrMS\-SI'   \1rNS\-SJ'    \2\:-  rOS\-SK'   \N\O-  rPS\-SL'    \3rQS\-SM'    \" SN\PSO9rR \" SP\NSO9rS \" SQ\OSO9rT\" SR\QSO9rU SbSS jrVScST jrW\" SU\5      rX\rYSV\-SW'   \rZSX\-SY'   \" SZ\5      r[\" S[\5      r\\" S\\5      r]SdS] jr^SeS^ jr_SfS_ jr`SgS` jraShSa jrbg)iu  The home for *mostly* [structural] counterparts to [nominal] native types.

If you find yourself being yelled at by a typechecker and ended up here - **do not fear!**

We have 5 funky flavors, which tackle two different problem spaces.

How do we describe [Native types] when ...
- ... **wrapping in** a [Narwhals type]?
- ... **matching to** an [`Implementation`]?

## Wrapping in a Narwhals type
[//]: # (TODO @dangotbanned: Replace `Thing` with a better name)

The following examples use the placeholder type `Thing` which represents one of:
- `DataFrame`: (Eager) 2D data structure representing data as a table with rows and columns.
- `LazyFrame`: (Lazy) Computation graph/query against a DataFrame/database.
- `Series`: 1D data structure representing a single column.

Our goal is to **wrap** a *partially-unknown* native object **in** a [generic class]:

    def wrapping_in_df(native: IntoDataFrameT) -> DataFrame[IntoDataFrameT]: ...
    def wrapping_in_lf(native: IntoLazyFrameT) -> LazyFrame[IntoLazyFrameT]: ...
    def wrapping_in_ser(native: IntoSeriesT) -> Series[IntoSeriesT]: ...

### (1) `Native<Thing>`
Minimal [`Protocol`]s that are [assignable to] *almost any* supported native type of that group:

    class NativeThing(Protocol):
        def something_common(self, *args: Any, **kwargs: Any) -> Any: ...

Note:
    This group is primarily a building block for more useful types.

### (2) `Into<Thing>`
*Publicly* exported [`TypeAlias`]s of **(1)**:

    IntoThing: TypeAlias = NativeThing

**But**, occasionally, there'll be an edge-case which we can spell like:

    IntoThing: TypeAlias = Union[<type that does not fit the protocol>, NativeThing]

Tip:
    Reach for these when there **isn't a need to preserve** the original native type.

### (3) `Into<Thing>T`
*Publicly* exported [`TypeVar`]s, bound to **(2)**:

    IntoThingT = TypeVar("IntoThingT", bound=IntoThing)

Important:
    In most situations, you'll want to use these as they **do preserve** the original native type.

Putting it all together, we can now add a *narwhals-level* wrapper:

    class Thing(Generic[IntoThingT]):
        def to_native(self) -> IntoThingT: ...

## Matching to an `Implementation`
This problem differs as we need to *create* a relationship between *otherwise-unrelated* types.

Comparing the problems side-by-side, we can more clearly see this difference:

    def wrapping_in_df(native: IntoDataFrameT) -> DataFrame[IntoDataFrameT]: ...
    def matching_to_polars(native: pl.DataFrame) -> Literal[Implementation.POLARS]: ...

### (4) `Native<Backend>`
If we want to describe a set of specific types and **match** them in [`@overload`s], then these the tools we need.

For common and easily-installed backends, [`TypeAlias`]s are composed of the native type(s):

    NativePolars: TypeAlias = pl.DataFrame | pl.LazyFrame | pl.Series

Otherwise, we need to define a [`Protocol`] which the native type(s) can **match** against *when* installed:

    class NativeDask(NativeLazyFrame, Protocol):
        _partition_type: type[pd.DataFrame]

Tip:
    The goal is to be as minimal as possible, while still being *specific-enough* to **not match** something else.

Important:
    See [ibis#9276 comment] for a more *in-depth* example that doesn't fit here 😄

### (5) `is_native_<backend>`
[Type guards] for **(4)**, *similar* to those found in `nw.dependencies`.

They differ by checking **all** native types/protocols in a single-call and using ``Native<Backend>`` aliases.

[structural]: https://typing.python.org/en/latest/spec/glossary.html#term-structural
[nominal]: https://typing.python.org/en/latest/spec/glossary.html#term-nominal
[Native types]: https://narwhals-dev.github.io/narwhals/how_it_works/#polars-and-other-implementations
[Narwhals type]: https://narwhals-dev.github.io/narwhals/api-reference/dataframe/
[`Implementation`]: https://narwhals-dev.github.io/narwhals/api-reference/implementation/
[`Protocol`]: https://typing.python.org/en/latest/spec/protocol.html
[assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable
[`TypeAlias`]: https://mypy.readthedocs.io/en/stable/kinds_of_types.html#type-aliases
[`TypeVar`]: https://mypy.readthedocs.io/en/stable/generics.html#type-variables-with-upper-bounds
[generic class]: https://docs.python.org/3/library/typing.html#user-defined-generic-types
[`@overload`s]: https://typing.python.org/en/latest/spec/overload.html
[ibis#9276 comment]: https://github.com/ibis-project/ibis/issues/9276#issuecomment-3292016818
[Type guards]: https://typing.python.org/en/latest/spec/narrowing.html
    )annotationsN)Callable
CollectionIterableSized)TYPE_CHECKINGAnyProtocolTypeVarcast)IMPORT_HOOKSget_cudf	get_modin
get_pandas
get_polarsget_pyarrowis_dask_dataframeis_duckdb_relationis_ibis_tableis_pyspark_connect_dataframeis_pyspark_dataframeis_sqlframe_dataframe)	TypeAlias)BaseDataFrame)SelfTypeIsTzCallable[[Any], TypeIs[T]]r   _Guard
Incomplete)+IntoDataFrameIntoDataFrameT	IntoFrame
IntoFrameTIntoLazyFrameIntoLazyFrameT
IntoSeriesIntoSeriesT	NativeAnyNativeArrow
NativeCuDF
NativeDaskNativeDataFrameNativeDuckDBNativeFrame
NativeIbisNativeKnownNativeLazyFrameNativeModinNativePandasNativePandasLikeNativePandasLikeDataFrameNativePandasLikeSeriesNativePolarsNativePySparkNativePySparkConnectNativeSQLFrameNativeSeriesNativeSparkLikeNativeUnknownis_native_arrowis_native_cudfis_native_daskis_native_duckdbis_native_ibisis_native_modinis_native_pandasis_native_pandas_likeis_native_polarsis_native_pysparkis_native_pyspark_connectis_native_spark_likeis_native_sqlframec                  2    \ rS rSr\SS j5       rSS jrSrg)r.      c                    g N selfs    L/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/narwhals/_native.pycolumnsNativeFrame.columns   s    !    c                    g rN   rO   rQ   argskwargss      rR   joinNativeFrame.join       crU   rO   Nreturnr	   rX   r	   rY   r	   r^   r	   )__name__
__module____qualname____firstlineno__propertyrS   rZ   __static_attributes__rO   rU   rR   r.   r.      s    ! !9rU   r.   c                      \ rS rSrSS jrSrg)r,      c                    g rN   rO   rW   s      rR   dropNativeDataFrame.drop   r\   rU   rO   Nr_   )r`   ra   rb   rc   ri   re   rO   rU   rR   r,   r,      s    9rU   r,   c                      \ rS rSrSS jrSrg)r1      c                    g rN   rO   rW   s      rR   explainNativeLazyFrame.explain   s    rU   rO   Nr_   )r`   ra   rb   rc   rn   re   rO   rU   rR   r1   r1      s    <rU   r1   c                  2    \ rS rSrSS jrSS jrSS jrSrg)r;      c                    g rN   rO   rW   s      rR   filterNativeSeries.filter       rU   c                    g rN   rO   rW   s      rR   value_countsNativeSeries.value_counts   s    crU   c                    g rN   rO   rW   s      rR   uniqueNativeSeries.unique   ru   rU   rO   Nr_   )r`   ra   rb   rc   rs   rw   rz   re   rO   rU   rR   r;   r;      s    ;A;rU   r;   c                      \ rS rSr% S\S'    SS jrSS jrSS jr\SS j5       r	\SS j5       r
S	S	S
.SS jjrSSS jjrSS jrSrg)_BasePandasLike   r	   indexc                   g rN   rO   )rQ   keys     rR   __getitem___BasePandasLike.__getitem__   s    srU   c                   g rN   rO   rQ   others     rR   __mul___BasePandasLike.__mul__   s    3rU   c                   g rN   rO   r   s     rR   __floordiv___BasePandasLike.__floordiv__   s    PSrU   c                    g rN   rO   rP   s    rR   loc_BasePandasLike.loc   s    rU   c                    g rN   rO   rP   s    rR   shape_BasePandasLike.shape   s    (+rU   .)axiscopyc                   g rN   rO   )rQ   labelsr   r   s       rR   set_axis_BasePandasLike.set_axis   s    SVrU   c                    g rN   rO   )rQ   deeps     rR   r   _BasePandasLike.copy   s    crU   c                    g)z`mypy` & `pyright` disagree on overloads.

`Incomplete` used to fix [more important issue](https://github.com/narwhals-dev/narwhals/pull/3016#discussion_r2296139744).
NrO   rQ   rX   kwdss      rR   rename_BasePandasLike.rename   s    rU   rO   N)r   r	   r^   r	   )r   z float | Collection[float] | Selfr^   r   r]   )r^   ztuple[int, ...])r   r	   r   r	   r   boolr^   r   .)r   r   r^   r   )rX   r	   r   r	   r^   Self | Incomplete)r`   ra   rb   rc   __annotations__r   r   r   rd   r   r   r   r   r   re   rO   rU   rR   r}   r}      s?    JK2NS + +36SV1rU   r}   c                      \ rS rSrSrg)_BasePandasLikeFrame   rO   N)r`   ra   rb   rc   re   rO   rU   rR   r   r      s    rU   r   c                  ^    \ rS rSr% S\S'       S             S	S jjrS
SS jjrSrg)_BasePandasLikeSeries   
Any | NonenameNc                    g rN   rO   )rQ   datar   dtyper   rX   rY   s          rR   __init___BasePandasLikeSeries.__init__   s     rU   c                   g rN   rO   )rQ   condr   s      rR   where_BasePandasLikeSeries.where   s    #rU   rO   )NNNN)r   Iterable[Any] | Noner   r   r   r   r   r   rX   r	   rY   r	   r^   Noner   )r   r	   r   r	   r^   r   )r`   ra   rb   rc   r   r   r   re   rO   rU   rR   r   r      sh    
 &*&* " $ 	
    
 NMrU   r   c                       \ rS rSr% S\S'   Srg)r+      type[pd.DataFrame]_partition_typerO   Nr`   ra   rb   rc   r   re   rO   rU   rR   r+   r+      s    ''rU   r+   c                      \ rS rSrSS jrSrg)_CuDFDataFrame   c                    g rN   rO   r   s      rR   to_pylibcudf_CuDFDataFrame.to_pylibcudf       CrU   rO   NrX   r	   r   r	   r^   r	   r`   ra   rb   rc   r   re   rO   rU   rR   r   r          ?rU   r   c                      \ rS rSrSS jrSrg)_CuDFSeriesi  c                    g rN   rO   r   s      rR   r   _CuDFSeries.to_pylibcudf  r   rU   rO   Nr   r   rO   rU   rR   r   r     r   rU   r   c                  <    \ rS rSrSS jrSS jrSS jrSS jrSrg)	r/   i  c                    g rN   rO   r   s      rR   sqlNativeIbis.sql  s    3rU   c                    g rN   rO   r   s      rR   __pyarrow_result__NativeIbis.__pyarrow_result__  s    #rU   c                    g rN   rO   r   s      rR   __pandas_result__NativeIbis.__pandas_result__      rU   c                    g rN   rO   r   s      rR   __polars_result__NativeIbis.__polars_result__	  r   rU   rO   Nr   )	r`   ra   rb   rc   r   r   r   r   re   rO   rU   rR   r/   r/     s    6EDDrU   r/   c                       \ rS rSr% S\S'   Srg)_ModinDataFramei  r   _pandas_classrO   Nr   rO   rU   rR   r   r     s    %%rU   r   c                       \ rS rSr% S\S'   Srg)_ModinSeriesi  ztype[pd.Series[Any]]r   rO   Nr   rO   rU   rR   r   r     s    ''rU   r   c                      \ rS rSrSS jrSrg)_PySparkDataFramei  c                    g rN   rO   )rQ   argrY   s      rR   dropDuplicatesWithinWatermark/_PySparkDataFrame.dropDuplicatesWithinWatermark  s    crU   rO   N)r   r	   rY   r	   r^   r	   )r`   ra   rb   rc   r   re   rO   rU   rR   r   r     s    QrU   r   z'pl.DataFrame | pl.LazyFrame | pl.Seriesr7   zpa.Table | pa.ChunkedArray[Any]r)   zduckdb.DuckDBPyRelationr-   zpd.DataFrame | pd.Series[Any]r3   z_ModinDataFrame | _ModinSeriesr2   z_CuDFDataFrame | _CuDFSeriesr*   z+pd.Series[Any] | _CuDFSeries | _ModinSeriesr6   z/pd.DataFrame | _CuDFDataFrame | _ModinDataFramer5   z2NativePandasLikeDataFrame | NativePandasLikeSeriesr4   z'_BaseDataFrame[Any, Any, Any, Any, Any]r:   r8   r9   z5NativeSQLFrame | NativePySpark | NativePySparkConnectr<   zhNativePolars | NativeArrow | NativePandasLike | NativeSparkLike | NativeDuckDB | NativeDask | NativeIbisr0   z0NativeDataFrame | NativeSeries | NativeLazyFramer=   zNativeKnown | NativeUnknownr(   r    r$   r"   r&   r#   )boundr!   r%   r'   c                    [        5       =nS L=(       a,    [        XR                  UR                  UR                  45      $ rN   )r   
isinstance	DataFrameSeries	LazyFrame)objpls     rR   rF   rF     s8    ,Bt+ 
llBIIr||41 rU   c                n    [        5       =nS L=(       a!    [        XR                  UR                  45      $ rN   )r   r   TableChunkedArray)r   pas     rR   r>   r>     s2    -B, hh(2 rU   z_Guard[NativeDask]z_Guard[NativeDuckDB]rA   z_Guard[NativeSQLFrame]rJ   z_Guard[NativePySpark]z_Guard[NativePySparkConnect]z_Guard[NativeIbis]c                   ^ ^ [        5       =nS L=(       a"    [        T UR                  UR                  45      =(       d    [	        UU 4S j[
         5       5      $ )Nc              3     >#    U  Hf  n[         R                  R                  US 5      =mS L=(       a6    [        TTR                  R
                  TR                  R                  45      v   Mh     g 7frN   )sysmodulesgetr   pandasr   r   ).0module_namemodr   s     rR   	<genexpr>#is_native_pandas.<locals>.<genexpr>  sb       (K T2	24? 	GsSZZ113::3D3DEF	G's   A.A1)r   r   r   r   anyr   )r   pdr   s   ` @rR   rD   rD     sL    |	D(WZbllBII=V-W	  ( 
rU   c                n    [        5       =nS L=(       a!    [        XR                  UR                  45      $ rN   )r   r   r   r   )r   mpds     rR   rC   rC     s2    ;Ct+ 
mmSZZ(1 rU   c                n    [        5       =nS L=(       a!    [        XR                  UR                  45      $ rN   )r   r   r   r   )r   cudfs     rR   r?   r?     s2    JDt+ 
nndkk*1 rU   c                `    [        U 5      =(       d    [        U 5      =(       d    [        U 5      $ rN   )rD   r?   rC   r   s    rR   rE   rE     s!    C ON3$7O?3;OOrU   c                `    [        U 5      =(       d    [        U 5      =(       d    [        U 5      $ rN   )rJ   rG   rH   r  s    rR   rI   rI     s)    3 	*S!	*$S)rU   )r   r	   r^   zTypeIs[NativePolars])r   r	   r^   zTypeIs[NativeArrow])r   r	   r^   zTypeIs[NativePandas])r   r	   r^   zTypeIs[NativeModin])r   r	   r^   zTypeIs[NativeCuDF])r   r	   r^   zTypeIs[NativePandasLike])r   r	   r^   zTypeIs[NativeSparkLike])c__doc__
__future__r   r   collections.abcr   r   r   r   typingr   r	   r
   r   r   narwhals.dependenciesr   r   r   r   r   r   r   r   r   r   r   r   r   duckdbr   r   polarsr   pyarrowr   sqlframe.base.dataframer   _BaseDataFrametyping_extensionsr   r   SQLFrameDataFramer   r   r   r   __all__r.   r,   r1   r;   r}   r   r   r+   r   r   r/   r   r   r   r7   r)   r-   r3   r2   r*   r6   r5   r4   r:   r8   r9   r<   r0   r=   r(   r    r$   r"   r&   r#   r!   r%   r'   rF   r>   r@   rA   rJ   rG   rH   rB   rD   rC   r?   rE   rI   rO   rU   rR   <module>r     s  fP # 
 A A > >     G.&sCc3'>?A4FI4J	,d:( ::e[( :=k8 =<5(3- <eX ( L?OX KNL/8 N(( (@)8 @@' @Eh E&*H &((( (R R Di C:Y :3i 39i 99Y 96
I 6$Q 	 Q'X 9 XR ) RE	 E,y ,"3 i 3T T DY  DMy M4	9 4*y *
 +Z7y 7$}4	9 4 %
I $ \3
 )? )?m:6 *,=>); & ;-B * B02FG  "$@  *M:PrU   