
    hhh:                    2   U d Z ddlmZ ddlmZmZmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZ e	rFddlZddlZddlZddl Z!ddl"m#Z$ ddl%m&Z&m'Z'm(Z( e$e
e
e
e
e
f         Z) ed	          Z*d
Z+de,d<   e
Z-de,d<   g dZ. G d de          Z/ G d dee/e          Z0 G d de/e          Z1 G d deee
         e          Z2 G d dee          Z3 G d de0e3e          Z4 G d de2e3e          Z5 G d de1e          Z6 G d d e4e          Z7 G d! d"e5e          Z8 G d# d$e/e          Z9 G d% d&e4e          Z: G d' d(e5e          Z; G d) d*e1e          Z<d+Z=de,d,<   d-Z>de,d.<   d/Z?de,d0<   d1Z@de,d2<   d3ZAde,d4<   d5ZBde,d6<   d7ZCde,d8<   d9ZDde,d:<   d;ZEde,d<<   d=ZFde,d><   e<ZGde,d?<   e<ZHde,d@<   dAZIde,dB<   dCZJde,dD<   dEZKde,dF<   dGZLde,dH<   e0ZMde,dI<   	 ee1e9f         ZNde,dJ<   eeMeNf         ZOde,dK<   	 e2ZPde,dL<   	  edMeON          ZQ	  edOeMN          ZR	  edPeNN          ZS edQePN          ZT	 dkdVZUdldXZV edYe          ZWeZXdZe,d[<   eZYd\e,d]<    ed^e          ZZ ed_e          Z[ ed`e          Z\dmdbZ]dnddZ^dodfZ_dpdhZ`dqdjZadS )ru  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
    )annotations)Callable
CollectionIterableSized)TYPE_CHECKINGAnyProtocolTypeVarUnioncast)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_dataframeN)BaseDataFrame)Self	TypeAlias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                  .    e Zd Zedd            Zd	dZdS )
r.   returnr	   c                    d S N selfs    G/var/www/histauto/venv/lib/python3.11/site-packages/narwhals/_native.pycolumnszNativeFrame.columns   s    !c    argskwargsc                    d S rN   rO   rQ   rU   rV   s      rR   joinzNativeFrame.join         rT   NrL   r	   rU   r	   rV   r	   rL   r	   )__name__
__module____qualname__propertyrS   rY   rO   rT   rR   r.   r.      s2        !!! X!999999rT   r.   c                      e Zd ZdS )r,   Nr]   r^   r_   rO   rT   rR   r,   r,                rT   r,   c                      e Zd ZddZdS )r1   rU   r	   rV   rL   c                    d S rN   rO   rX   s      rR   explainzNativeLazyFrame.explain   rZ   rT   Nr\   )r]   r^   r_   rf   rO   rT   rR   r1   r1      s        <<<<<<rT   r1   c                      e Zd ZddZdS )r;   rU   r	   rV   rL   c                    d S rN   rO   rX   s      rR   filterzNativeSeries.filter   rZ   rT   Nr\   )r]   r^   r_   ri   rO   rT   rR   r;   r;      s        ;;;;;;rT   r;   c                      e Zd ZU ded<   	 ddZdd	Zdd
Zedd            Zedd            Z	dddd dZ
d!d"dZd#dZdS )$_BasePandasLiker	   indexkeyrL   c                   d S rN   rO   )rQ   rm   s     rR   __getitem__z_BasePandasLike.__getitem__   rZ   rT   other float | Collection[float] | Selfr   c                   d S rN   rO   rQ   rp   s     rR   __mul__z_BasePandasLike.__mul__   rZ   rT   c                   d S rN   rO   rs   s     rR   __floordiv__z_BasePandasLike.__floordiv__   rZ   rT   c                    d S rN   rO   rP   s    rR   locz_BasePandasLike.loc   s    #rT   tuple[int, ...]c                    d S rN   rO   rP   s    rR   shapez_BasePandasLike.shape   s    (+rT   .)axiscopylabelsr|   r}   boolc                   d S rN   rO   )rQ   r~   r|   r}   s       rR   set_axisz_BasePandasLike.set_axis   rZ   rT   deepc                    d S rN   rO   )rQ   r   s     rR   r}   z_BasePandasLike.copy   rZ   rT   rU   kwdsSelf | Incompletec                    dS )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   rU   r   s      rR   renamez_BasePandasLike.rename   rZ   rT   N)rm   r	   rL   r	   )rp   rq   rL   r   r[   )rL   ry   )r~   r	   r|   r	   r}   r   rL   r   .)r   r   rL   r   )rU   r	   r   r	   rL   r   )r]   r^   r_   __annotations__ro   rt   rv   r`   rx   r{   r   r}   r   rO   rT   rR   rk   rk      s         JJJK2222NNNNSSSS X+++ X+36SVVVVVV11111     rT   rk   c                      e Zd ZdS )_BasePandasLikeFrameNrb   rO   rT   rR   r   r      rc   rT   r   c                      e Zd Zd	d
dZdS )_BasePandasLikeSeries.condr	   rp   rL   r   c                   d S rN   rO   )rQ   r   rp   s      rR   wherez_BasePandasLikeSeries.where   rZ   rT   Nr   )r   r	   rp   r	   rL   r   )r]   r^   r_   r   rO   rT   rR   r   r      s        MMMMMMMrT   r   c                      e Zd ZU ded<   dS )r+   type[pd.DataFrame]_partition_typeNr]   r^   r_   r   rO   rT   rR   r+   r+               ''''''rT   r+   c                      e Zd ZddZdS )_CuDFDataFramerU   r	   r   rL   c                    d S rN   rO   r   s      rR   to_pylibcudfz_CuDFDataFrame.to_pylibcudf   rZ   rT   NrU   r	   r   r	   rL   r	   r]   r^   r_   r   rO   rT   rR   r   r              ??????rT   r   c                      e Zd ZddZdS )_CuDFSeriesrU   r	   r   rL   c                    d S rN   rO   r   s      rR   r   z_CuDFSeries.to_pylibcudf   rZ   rT   Nr   r   rO   rT   rR   r   r      r   rT   r   c                  .    e Zd Zd
dZd
dZd
dZd
dZd	S )r/   rU   r	   r   rL   c                    d S rN   rO   r   s      rR   sqlzNativeIbis.sql   rZ   rT   c                    d S rN   rO   r   s      rR   __pyarrow_result__zNativeIbis.__pyarrow_result__   rZ   rT   c                    d S rN   rO   r   s      rR   __pandas_result__zNativeIbis.__pandas_result__   rZ   rT   c                    d S rN   rO   r   s      rR   __polars_result__zNativeIbis.__polars_result__   rZ   rT   Nr   )r]   r^   r_   r   r   r   r   rO   rT   rR   r/   r/      s@        6666EEEEDDDDDDDDDDrT   r/   c                      e Zd ZU ded<   dS )_ModinDataFramer   _pandas_classNr   rO   rT   rR   r   r      s         %%%%%%rT   r   c                      e Zd ZU ded<   dS )_ModinSeriesztype[pd.Series[Any]]r   Nr   rO   rT   rR   r   r      r   rT   r   c                      e Zd ZddZdS )_PySparkDataFrameargr	   rV   rL   c                    d S rN   rO   )rQ   r   rV   s      rR   dropDuplicatesWithinWatermarkz/_PySparkDataFrame.dropDuplicatesWithinWatermark  rZ   rT   N)r   r	   rV   r	   rL   r	   )r]   r^   r_   r   rO   rT   rR   r   r     s        QQQQQQrT   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'   objr	   rL   TypeIs[NativePolars]c                j    t                      x}d uo!t          | |j        |j        |j        f          S rN   )r   
isinstance	DataFrameSeries	LazyFrame)r   pls     rR   rF   rF   n  s;    ,,Bt+ 
blBIr|41 1 rT   TypeIs[NativeArrow]c                ^    t                      x}d uot          | |j        |j        f          S rN   )r   r   TableChunkedArray)r   pas     rR   r>   r>   t  s7    --B, bh(2 2 rT   z_Guard[NativeDask]z_Guard[NativeDuckDB]rA   z_Guard[NativeSQLFrame]rJ   z_Guard[NativePySpark]z_Guard[NativePySparkConnect]z_Guard[NativeIbis]TypeIs[NativePandas]c                ^    t                      x}d uot          | |j        |j        f          S rN   )r   r   r   r   )r   pds     rR   rD   rD     s.    ,,Bt+Z
3ry@Y0Z0ZZrT   TypeIs[NativeModin]c                ^    t                      x}d uot          | |j        |j        f          S rN   )r   r   r   r   )r   mpds     rR   rC   rC     s7    ;;Ct+ 
cmSZ(1 1 rT   TypeIs[NativeCuDF]c                ^    t                      x}d uot          | |j        |j        f          S rN   )r   r   r   r   )r   cudfs     rR   r?   r?     s7    JJDt+ 
dndk*1 1 rT   TypeIs[NativePandasLike]c                \    t          |           pt          |           pt          |           S rN   )rD   r?   rC   r   s    rR   rE   rE     s*    C  ON3$7$7O?3;O;OOrT   TypeIs[NativeSparkLike]c                \    t          |           pt          |           pt          |           S rN   )rJ   rG   rH   r   s    rR   rI   rI     s2    3 	*S!!	*$S))rT   )r   r	   rL   r   )r   r	   rL   r   )r   r	   rL   r   )r   r	   rL   r   )r   r	   rL   r   )r   r	   rL   r   )r   r	   rL   r   )b__doc__
__future__r   collections.abcr   r   r   r   typingr   r	   r
   r   r   r   narwhals.dependenciesr   r   r   r   r   r   r   r   r   r   r   duckdbpandasr   polarsr   pyarrowr   sqlframe.base.dataframer   _BaseDataFrametyping_extensionsr   r   r   SQLFrameDataFramer   r   r   r   __all__r.   r,   r1   r;   rk   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   rT   rR   <module>r      sR  f f fP # " " " " " A A A A A A A A A A A A E E E E E E E E E E E E E E E E                            MMMGGGGGG9999999999&sCc3'>?A4F4444J, , ,d: : : : :( : : : 9 8 8 8 8e[( 8 8 8= = = = =k8 = = =< < < < <5(3- < < <    eX   ( L K K K K?OX K K KN N N N NL/8 N N N( ( ( ( (( ( ( (@ @ @ @ @)8 @ @ @@ @ @ @ @' @ @ @E E E E Eh E E E& & & & &*H & & &( ( ( ( ((( ( ( (R R R R R R R R D C C C C: : : : :3 3 3 3 39 9 9 9 99 9 9 9 96
 6 6 6 6$Q  Q Q Q Q'X  X X X XR  R R R RE E E E E, , , , ,"3  3 3 3 3T T T T T D  D  D  D  DM M M M M4	 4 4 4 4* * * * *
 !*!<= = = = =]M9:	 : : : : %
 $ $ $ $ W\333
 )??? )???gm:666       *,=>>);  ; ; ; ;-B  B B B BD02FGG  D"$@   *M::[ [ [ [      P P P P     rT   