ó
    - j=  ã                  ó–  • % 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    ÚžC:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\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ØÛó ØØÛ+ó Ø+Ø36ÀS×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   € Ü“,ÐˆB tÐ+÷ ´
Ø�l‰l˜BŸI™I r§|¡|Ð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¨Ð,÷ ´Ø�h‰h˜Ÿ™Ð(ó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Ü�s˜SŸZ™Z×1Ñ1°3·:±:×3DÑ3DÐEÓFô	Gâ'ùs   ƒA.A1)r   rå   ræ   rç   Úanyr   )ré   Úpdr÷   s   ` @rR   rD   rD   –  sL   ù€ ä‹|Ð	ˆ DÐ(×W¬Z¸¸b¿l¹lÈBÏIÉIÐ=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   € Ü“;ÐˆC tÐ+÷ ´
Ø�m‰m˜SŸZ™ZÐ(ó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ÐˆD tÐ+÷ ´
Ø�n‰n˜dŸk™kÐ*ó1ð rU   c                ó`   • [        U 5      =(       d    [        U 5      =(       d    [        U 5      $ rN   )rD   r?   rC   ©ré   s    rR   rE   rE   ¬  s!   € Ü˜CÓ ×O¤N°3Ó$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ß.à& s¨C°°c¸3Ð'>Ñ?ÐÙ�‹€AØ4€FˆIÓ4Ø€J�	Óò,€ôd:�(ô :ô:�e˜[¨(ô :ô=�k 8ô =ô<�5˜( 3™-¨ô <ô�e˜Xô ô( L˜?¨O¸XÔ 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ÙÐ0Ð2FÓGÐ Ù Ø"Ð$@óÐ ñ Ð*¨MÓ:€ôôôôPõrU   