
    O3j2                       d 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
mZ ddlmZmZmZ ddlmZmZmZmZmZmZmZ e
r.dd	lmZ dd
l	mZ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$m%Z%m&Z&m'Z' dgZ( G d dee)df         Z*y)zxSchema.

Adapted from Polars implementation at:
https://github.com/pola-rs/polars/blob/main/py-polars/polars/schema.py.
    )annotations)OrderedDict)Mapping)partial)TYPE_CHECKINGcast)ImplementationVersionqualified_type_name)get_cudfis_cudf_dtypeis_pandas_like_dtypeis_polars_data_typeis_polars_schemais_pyarrow_data_typeis_pyarrow_schema)Iterable)AnyClassVarN)Self)DType)DTypeBackendIntoArrowSchemaIntoPandasSchemaIntoPolarsSchemaSchemac                      e Zd ZU dZej
                  Zded<   	 d	 	 	 d fdZddZ	ddZ
ddZedd       Zedd	       Ze	 	 	 	 dd
       Zedd       ZddZ	 d	 	 	 ddZddZe	 	 	 	 dd       Ze	 	 	 	 	 	 dd       Z xZS )r   an  Ordered mapping of column names to their data type.

    Note:
        The pandas-like and dask backends allow non-string column names
        (e.g. integers or booleans). While discouraged, this is supported,
        so we cannot guarantee that the keys are strictly strings.

        See [concepts - column names](../concepts/column_names.md) for details.

    Arguments:
        schema: The schema definition given by column names and their associated
            *instantiated* Narwhals data type. Accepts a mapping or an iterable of tuples.

    Examples:
        Define a schema by passing *instantiated* data types.

        >>> import narwhals as nw
        >>> schema = nw.Schema({"foo": nw.Int8(), "bar": nw.String()})
        >>> schema
        Schema({'foo': Int8, 'bar': String})

        Access the data type associated with a specific column name.

        >>> schema["foo"]
        Int8

        Access various schema properties using the `names`, `dtypes`, and `len` methods.

        >>> schema.names()
        ['foo', 'bar']
        >>> schema.dtypes()
        [Int8, String]
        >>> schema.len()
        2
    zClassVar[Version]_versionc                0    |xs i }t         |   |       y N)super__init__)selfschema	__class__s     </DATA/.local/lib/python3.12/site-packages/narwhals/schema.pyr"   zSchema.__init__T   s     2     c                4    t        | j                               S )ao  Get the column names of the schema.

        Note:
            The pandas-like and dask backends allow non-string column names
            (e.g. integers or booleans). While discouraged, this is supported,
            so the return type is not guaranteed to be `list[str]`.

            See [concepts - column names](../concepts/column_names.md) for details.
        )listkeysr#   s    r&   nameszSchema.namesZ   s     DIIK  r'   c                4    t        | j                               S )z!Get the data types of the schema.)r)   valuesr+   s    r&   dtypeszSchema.dtypesf   s    DKKM""r'   c                    t        |       S )z(Get the number of columns in the schema.)lenr+   s    r&   r1   z
Schema.lenj   s    4yr'   c                    t        |t              r|s         S ddl} |j                  |      }ddlm    fd|D              S )a  Construct a Schema from a pyarrow Schema.

        Arguments:
            schema: A pyarrow Schema or mapping of column names to pyarrow data types.

        Examples:
            >>> import pyarrow as pa
            >>> import narwhals as nw
            >>>
            >>> mapping = {
            ...     "a": pa.timestamp("us", "UTC"),
            ...     "b": pa.date32(),
            ...     "c": pa.string(),
            ...     "d": pa.uint8(),
            ... }
            >>> native = pa.schema(mapping)
            >>>
            >>> nw.Schema.from_arrow(native)
            Schema({'a': Datetime(time_unit='us', time_zone='UTC'), 'b': Date, 'c': String, 'd': UInt8})

            >>> nw.Schema.from_arrow(mapping) == nw.Schema.from_arrow(native)
            True
        r   Nnative_to_narwhals_dtypec              3  p   K   | ]-  }|j                    |j                  j                        f / y wr    )nametyper   ).0fieldclsr4   s     r&   	<genexpr>z$Schema.from_arrow.<locals>.<genexpr>   s2      
 ZZ1%**cllKLs   36)
isinstancer   pyarrowr$   narwhals._arrow.utilsr4   )r:   r$   par4   s   `  @r&   
from_arrowzSchema.from_arrown   sI    2 fg&u RYYv&FB 

 
 	
r'   c                   |s |        S t               r0t        d |j                         D              rt        j                  nt        j
                  }| j                  ||      S )a3  Construct a Schema from a pandas-like schema representation.

        Arguments:
            schema: A mapping of column names to pandas-like data types.

        Examples:
            >>> import numpy as np
            >>> import pandas as pd
            >>> import pyarrow as pa
            >>> import narwhals as nw
            >>>
            >>> data = {"a": [1], "b": ["a"], "c": [False], "d": [9.2]}
            >>> native = pd.DataFrame(data).convert_dtypes().dtypes.to_dict()
            >>>
            >>> nw.Schema.from_pandas_like(native)
            Schema({'a': Int64, 'b': String, 'c': Boolean, 'd': Float64})
            >>>
            >>> mapping = {
            ...     "a": pd.DatetimeTZDtype("us", "UTC"),
            ...     "b": pd.ArrowDtype(pa.date32()),
            ...     "c": pd.StringDtype("python"),
            ...     "d": np.dtype("uint8"),
            ... }
            >>>
            >>> nw.Schema.from_pandas_like(mapping)
            Schema({'a': Datetime(time_unit='us', time_zone='UTC'), 'b': Date, 'c': String, 'd': UInt8})
        c              3  2   K   | ]  }t        |        y wr    )r   )r8   dtypes     r&   r;   z*Schema.from_pandas_like.<locals>.<genexpr>   s     !TO5-"6Os   )r   anyr.   r	   CUDFPANDAS_from_pandas_like)r:   r$   impls      r&   from_pandas_likezSchema.from_pandas_like   sV    : 5L zc!TFMMO!TT && 	
 $$VT22r'   c                   t        |      r| j                  |      S t        |      r| j                  |      S t	        |t
              r|r| j                  |      S  |        S dt        |      d|}t        |      )ao  Construct a Schema from a native schema representation.

        Arguments:
            schema: A native schema object, or mapping of column names to
                *instantiated* native data types.

        Examples:
            >>> import datetime as dt
            >>> import pyarrow as pa
            >>> import narwhals as nw
            >>>
            >>> data = {"a": [1], "b": ["a"], "c": [dt.time(1, 2, 3)], "d": [[2]]}
            >>> native = pa.table(data).schema
            >>>
            >>> nw.Schema.from_native(native)
            Schema({'a': Int64, 'b': String, 'c': Time, 'd': List(Int64)})
        z5Expected an arrow, polars, or pandas schema, but got z

)	r   r@   r   from_polarsr<   r   _from_native_mappingr   	TypeError)r:   r$   msgs      r&   from_nativezSchema.from_native   s    * V$>>&))F#??6**fg&7=3++F3H35HC"6*-T&= 	 nr'   c               d     |s         S ddl m    fd|j                         D              S )a/  Construct a Schema from a polars Schema.

        Arguments:
            schema: A polars Schema or mapping of column names to *instantiated*
                polars data types.

        Examples:
            >>> import polars as pl
            >>> import narwhals as nw
            >>>
            >>> mapping = {
            ...     "a": pl.Datetime(time_zone="UTC"),
            ...     "b": pl.Date(),
            ...     "c": pl.String(),
            ...     "d": pl.UInt8(),
            ... }
            >>> native = pl.Schema(mapping)
            >>>
            >>> nw.Schema.from_polars(native)
            Schema({'a': Datetime(time_unit='us', time_zone='UTC'), 'b': Date, 'c': String, 'd': UInt8})

            >>> nw.Schema.from_polars(mapping) == nw.Schema.from_polars(native)
            True
        r   r3   c              3  N   K   | ]  \  }}| |j                         f  y wr    r   )r8   r6   rC   r:   r4   s      r&   r;   z%Schema.from_polars.<locals>.<genexpr>   s.      
-e +E3<<@A-   "%)narwhals._polars.utilsr4   items)r:   r$   r4   s   ` @r&   rK   zSchema.from_polars   s2    4 5LC 
%||~
 
 	
r'   c                n     ddl }ddlm  |j                   fd j	                         D              S )a  Convert Schema to a pyarrow Schema.

        Examples:
            >>> import narwhals as nw
            >>> schema = nw.Schema({"a": nw.Int64(), "b": nw.Datetime("ns")})
            >>> schema.to_arrow()
            a: int64
            b: timestamp[ns]
        r   Nnarwhals_to_native_dtypec              3  N   K   | ]  \  }}| |j                         f  y wr    rR   r8   r6   rC   rX   r#   s      r&   r;   z"Schema.to_arrow.<locals>.<genexpr>  s.      
+e +E4==AB+rS   )r=   r>   rX   r$   rU   )r#   r?   rX   s   ` @r&   to_arrowzSchema.to_arrow   s1     	Bryy 
#zz|
 
 	
r'   c                   ddl m} t        |t        j                  | j
                        }|t        |t              r,| j                         D ci c]  \  }}| |||       c}}S t        |      }t        |      t        |       k7  rnddlm}m}m}	 t        |      t        |       }}
t         ||j                   | |	|      |            |            }d|
d|d| d	|d    d
| d}t!        |      t#        | j%                         | j'                         |d      D ci c]  \  }}}| |||       c}}}S c c}}w c c}}}w )am  Convert Schema to an ordered mapping of column names to their pandas data type.

        Arguments:
            dtype_backend: Backend(s) used for the native types. When providing more than
                one, the length of the iterable must be equal to the length of the schema.

        Examples:
            >>> import narwhals as nw
            >>> schema = nw.Schema({"a": nw.Int64(), "b": nw.Datetime("ns")})
            >>> schema.to_pandas()
            {'a': 'int64', 'b': 'datetime64[ns]'}

            >>> schema.to_pandas("pyarrow")
            {'a': 'Int64[pyarrow]', 'b': 'timestamp[ns][pyarrow]'}
        r   rW   )implementationversion)rC   dtype_backend)chainislicerepeatz	Provided z) `dtype_backend`(s), but schema contains z1 field(s).
Hint: instead of
    schema.to_pandas(z+)
you may want to use
    schema.to_pandas(z)
or
    schema.to_pandas()T)strict)narwhals._pandas_like.utilsrX   r   r	   rF   r   r<   strrU   tupler1   	itertoolsr`   ra   rb   from_iterable
ValueErrorzipr*   r.   )r#   r_   rX   to_native_dtyper6   rC   backendsr`   ra   rb   n_usern_actual
suggestionrN   backends                  r&   	to_pandaszSchema.to_pandas  su   $ 	I!$)00MM

  J}c$B $(::<#/KD% oEOO#/  'x=CI%77"8}c$iHFu**6&2BH+MNPXYJ F:%Nxl [((0z 2((0} 5((2|16  S/! ),		T[[]HT)
)$eW /WEE)
 	
-,
s   E*Ec                     ddl }ddlm t        j                  j                         } fd j                         D        }|dk\  r |j                  |      S t        dt        |            S )a%  Convert Schema to a polars Schema.

        Examples:
            >>> import narwhals as nw
            >>> schema = nw.Schema({"a": nw.Int64(), "b": nw.Datetime("ns")})
            >>> schema.to_polars()
            Schema({'a': Int64, 'b': Datetime(time_unit='ns', time_zone=None)})
        r   NrW   c              3  N   K   | ]  \  }}| |j                         f  y wr    rR   rZ   s      r&   r;   z#Schema.to_polars.<locals>.<genexpr>V  s.      
+e +E4==AB+rS   )   r   r   	pl.Schema)
polarsrT   rX   r	   POLARS_backend_versionrU   r   r   dict)r#   pl
pl_versionr$   rX   s   `   @r&   	to_polarszSchema.to_polarsH  sh     	C#**;;=

#zz|
 Y& BIIf	
 k4<0	
r'   c               r   t        t        |j                                     }|\  }}t        |      r| j	                  t        d|            S t        |      r| j                  t        d|            S t        |      r| j                  t        d|            S d| dt        |       d|}t        |      )Nr   r   r   z7Expected an arrow, polars, or pandas dtype, but found `z: z`

)nextiterrU   r   rK   r   r   rI   r   r@   r   rM   )r:   native
first_item	first_keyfirst_dtyperN   s         r&   rL   zSchema._from_native_mapping`  s     $v||~./
!+	;{+??4(:F#CDD,''-?(HII,>>$'8&"ABB{"0=>eF:O 	 nr'   c               Z     ddl m |   fd|j                         D              S )Nr   r3   c              3  T   K   | ]  \  }}| |j                   d       f ! yw)T)allow_objectNrR   )r8   r6   rC   r:   rH   r4   s      r&   r;   z+Schema._from_pandas_like.<locals>.<genexpr>{  s3      
-e +E3<<TXYZ-s   %()re   r4   rU   )r:   r$   r]   rH   r4   s   `  @@r&   rG   zSchema._from_pandas_liket  s.     	I 
%||~
 
 	
r'   r    )r$   z8Mapping[str, DType] | Iterable[tuple[str, DType]] | NonereturnNone)r   z	list[str])r   zlist[DType])r   int)r$   r   r   r   )r$   r   r   r   )r$   z5IntoArrowSchema | IntoPolarsSchema | IntoPandasSchemar   r   )r$   r   r   r   )r   z	pa.Schema)r_   z%DTypeBackend | Iterable[DTypeBackend]r   zdict[str, Any])r   rv   )r   zHMapping[str, pa.DataType] | Mapping[str, pl.DataType] | IntoPandasSchemar   r   )r$   r   r]   r	   r   r   )__name__
__module____qualname____doc__r
   MAINr   __annotations__r"   r,   r/   r1   classmethodr@   rI   rO   rK   r[   rr   r}   rL   rG   __classcell__)r%   s   @r&   r   r   -   s"   "H #*,,H. RV!N!	!
!# #
 #
J #3 #3J J	 @  
  
D
( FJ5
B5
	5
n
0 X 
	 & 	
%	
7E	
		
 	
r'   r   )+r   
__future__r   collectionsr   collections.abcr   	functoolsr   typingr   r   narwhals._utilsr	   r
   r   narwhals.dependenciesr   r   r   r   r   r   r   r   r   r   rw   r{   r=   r?   typing_extensionsr   narwhals.dtypesr   narwhals.typingr   r   r   r   __all__rf   r    r'   r&   <module>r      sq    # # #  & H H   ($&%  *Q
[g& Q
r'   