U
    Cvfq                     @  s  d dl mZ d dl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 d dlZd dlmZ d dlmZ d dlmZ d dlmZmZmZmZmZ d d	lmZm Z m!Z!m"Z" d d
l#m$Z$m%Z%m&Z& erd dl'm(Z( d dl)m*Z* d dl+m,Z, d dl-m.Z.m/Z/m0Z0 eeee f Z1eZ2ee2ee1e2f ee1e2e
f ee1e2e
e
f f Z3ee*e$e3f Z4ee,e
ee4f f Z5ee4ej6ej7f Z8ee,e
ee8f f Z9ej6ej7fZ:ed ddddddZ;G dd dZ<dddddZ=G dd de>Z?dwddd d!d"d#d$d%Z@d&d' ZAee$ee f ZBd(d)d*d+d,d-ZCdxd(d0d d1d2d3d4d5d6ZDdyd7d8d(d9d:d;ZEd<d(d=d>d?ZFdeG d/fd<d0d@d1d3dAdBdCZHdDdEdFdGdHZIdId7dJdKdLZJdzd7dNd dOdPdQdRZKd.dSddejLfdId dTdNdUdVd3dWdXdYZMd{dZd[ZNd|d\d]ZOd^d_ ZPd}d`daZQG dbdc dceZRddSd/dddejLfdId dTd1dNddd8dVdcde	dfdgZSdhdSejLd/fdid dTdVd1djdkdldmZTdjdndod dTdpd1dcdqdrdsZUdjdndcdtdudvZVdS )~    )annotations)defaultdict)TYPE_CHECKINGAbstractSetAnyHashableIterableMapping
NamedTupleOptionalSequenceTupleUnionN)dtypes)
deep_align)lazy_array_equiv)IndexIndexescreate_default_index_implicitfilter_indexes_from_coordsindexes_equal)Frozencompat_dict_union
dict_equiv
equivalent)Variableas_variablecalculate_dimensions)Coordinates	DataArrayDataset)CombineAttrsOptionsCompatOptionsJoinOptions               )	identicalequalsbroadcast_equalsminimalno_conflictsoverridec                   @  s   e Zd ZdZdd ZdS )Contextz)object carrying the information of a callc                 C  s
   || _ d S N)func)selfr3    r5   5/tmp/pip-unpacked-wheel-h316xyqg/xarray/core/merge.py__init__F   s    zContext.__init__N)__name__
__module____qualname____doc__r7   r5   r5   r5   r6   r1   C   s   r1   zlist[Variable]dict[Hashable, int])	variablesreturnc                 C  sV   i }| D ]H}t |j|jD ]4\}}||krF||| krFtd|d|||< qq|S )z{Extract dimension sizes from a dictionary of variables.

    Raises ValueError if any dimensions have different sizes.
    zindex z not aligned)zipdimsshape
ValueError)r=   r@   vardimsizer5   r5   r6   broadcast_dimension_sizeJ   s    rF   c                   @  s   e Zd ZdZdS )
MergeErrorz=Error class for merge failures due to incompatible arguments.N)r8   r9   r:   r;   r5   r5   r5   r6   rG   X   s   rG   r-   r   r$   zbool | Noner   )namer=   compatr,   r>   c                 C  s  |d }t |dks|dkr |S d}|dkr0d}|dkrJt|}||}|dkrVd}|dkr|dd D ]"}t|||td	}|d
k	rj qqj|dkr| }|dd D ]}t|||}|s qq|std| d|r|dd D ]}t|||}q|S )a  Return the unique variable from a list of variables or raise MergeError.

    Parameters
    ----------
    name : hashable
        Name for this variable.
    variables : list of Variable
        List of Variable objects, all of which go by the same name in different
        inputs.
    compat : {"identical", "equals", "broadcast_equals", "no_conflicts", "override"}, optional
        Type of equality check to use.
    equals : None or bool, optional
        corresponding to result of compat test

    Returns
    -------
    Variable to use in the result.

    Raises
    ------
    MergeError: if any of the variables are not equal.
    r   r&   r0   Nr.   r-   r/   Zfillna)equivTz conflicting values for variable zT on objects to be combined. You can skip this check by specifying compat='override'.)lenrF   Zset_dimsgetattrr   ZcomputerG   )rH   r=   rI   r,   outZcombine_methodZdim_lengthsrC   r5   r5   r6   unique_variable_   s<    

rN   c                 C  s$   | t kr td| dtt  d S )Nzcompat=z invalid: must be )_VALID_COMPATrB   setrI   r5   r5   r6   _assert_compat_valid   s    rR   z"dict[Hashable, list[MergeElement]]zMapping[Any, MergeElement]None)groupedprioritizedr>   c              	   C  s   t |}tt}i }|  D ]<\}}|D ].\}}|dk	r(|t| | ||t|< q(q| D ]r\}	}
t |
}||@ }|rbt|t|krbddd |D }ddd |
D }td| d| d||	 qbdS )	zbMake sure that elements given in prioritized will not corrupt any
    index given in grouped.
    Nz, c                 s  s   | ]}|V  qd S r2   r5   .0kr5   r5   r6   	<genexpr>   s     z,_assert_prioritized_valid.<locals>.<genexpr>c                 s  s   | ]}|V  qd S r2   r5   rV   r5   r5   r6   rY      s     z!cannot set or update variable(s) zA, which would corrupt the following index built from coordinates z:
)	rP   r   listitemsidappendrK   joinrB   )rT   rU   Zprioritized_namesZgrouped_by_indexindexesrH   elements_list_indexZindex_idZindex_coord_namesZindex_namesZcommon_namesZcommon_names_strZindex_names_strr5   r5   r6   _assert_prioritized_valid   s"    rc   r.   r0   z!Mapping[Any, MergeElement] | Noner#   zdict[Hashable, bool] | Nonez6tuple[dict[Hashable, Variable], dict[Hashable, Index]])rT   rU   rI   combine_attrsr,   r>   c                 C  s  |dkri }|dkri }t | t| | i }i }i }|  D ]\}}	||krv|| \}
}|
||< |dk	rt|||< q>dd |	D }|r^|d \}
}|dd D ]@\}}t|||
||std|d|d|d	|
d
|dq|dkr0|dd D ]4\}}t|
j|jstd|d|
jd|jq|
||< tdd |D |d|| _|||< q>dd |	D }zt||||	|d||< W n" tk
r   |dkr Y nX ||kr>tdd |D |d|| _q>||fS )aE  Merge dicts of variables, while resolving conflicts appropriately.

    Parameters
    ----------
    grouped : mapping
    prioritized : mapping
    compat : str
        Type of equality check to use when checking for conflicts.
    combine_attrs : {"drop", "identical", "no_conflicts", "drop_conflicts",                     "override"} or callable, default: "override"
        A callable or a string indicating how to combine attrs of the objects being
        merged:

        - "drop": empty attrs on returned Dataset.
        - "identical": all attrs must be the same on every object.
        - "no_conflicts": attrs from all objects are combined, any that have
          the same name must also have the same value.
        - "drop_conflicts": attrs from all objects are combined, any that have
          the same name but different values are dropped.
        - "override": skip comparing and copy attrs from the first dataset to
          the result.

        If a callable, it must expect a sequence of ``attrs`` dicts and a context object
        as its only parameters.
    equals : mapping, optional
        corresponding to result of compat test

    Returns
    -------
    Dict with keys taken by the union of keys on list_of_mappings,
    and Variable values corresponding to those that should be found on the
    merged result.
    Nc                 S  s    g | ]\}}|d k	r||fqS r2   r5   rW   variablerb   r5   r5   r6   
<listcomp>  s   z#merge_collected.<locals>.<listcomp>r   r&   zCconflicting values/indexes on objects to be combined fo coordinate z
first index: z
second index: z
first variable: z
second variable: 
r+   z2conflicting attribute values on combined variable z:
first value: z
second value: c                 S  s   g | ]\}}|j qS r5   attrs)rW   rC   ra   r5   r5   r6   rg   '  s     rd   c                 S  s   g | ]\}}|qS r5   r5   )rW   rf   ra   r5   r5   r6   rg   ,  s     r.   c                 S  s   g | ]
}|j qS r5   ri   rW   rC   r5   r5   r6   rg   9  s     )
rR   rc   r[   r   rG   r   rj   merge_attrsrN   get)rT   rU   rI   rd   r,   Zmerged_varsmerged_indexesZindex_cmp_cacherH   r`   rf   rb   Zindexed_elementsZ	other_varZother_indexZother_variablera   r=   r5   r5   r6   merge_collected   sx    (

    "

   

 rp   zlist[DatasetLike]zMapping[Any, Any] | None)list_of_mappingsr_   r>   c                   s$  ddl m} ddlm} |dkr$i }ttfdd  fdd}| D ]}t||rf||j|j qH|	 D ]\}}t||r|j
 }t|j}	||d |	|d |||	 t||d	}||kr܈ ||||  qn|j|fkrt|\}
||
fd
d|
D  qn ||d qnqHS )a  Collect variables and indexes from list of mappings of xarray objects.

    Mappings must either be Dataset objects, or have values of one of the
    following types:
    - an xarray.Variable
    - a tuple `(dims, data[, attrs[, encoding]])` that can be converted in
      an xarray.Variable
    - or an xarray.DataArray

    If a mapping of indexes is given, those indexes are assigned to all variables
    with a matching key/name.

    r   r   r!   Nc                   s    |   ||f d S r2   r]   )rH   rf   rb   )rT   r5   r6   r]   X  s    z-collect_variables_and_indexes.<locals>.appendc                   s(   |   D ]\}} |||| qd S r2   )r[   rn   )r=   r_   rH   rf   rr   r5   r6   
append_all[  s    z1collect_variables_and_indexes.<locals>.append_allrH   c                   s   i | ]
}| qS r5   r5   rV   idxr5   r6   
<dictcomp>r  s      z1collect_variables_and_indexes.<locals>.<dictcomp>)xarray.core.dataarrayr    xarray.core.datasetr"   r   rZ   
isinstancer=   Z_indexesr[   _coordscopydictpopr   r@   r   )rq   r_   r    r"   rs   mappingrH   rf   Zcoords_Zindexes_idx_varsr5   )r]   rT   rv   r6   collect_variables_and_indexes?  s4    




r   zlist[Coordinates])list_of_coordsr>   c                 C  sL   t t}| D ]:}|j}|j}| D ] \}}|| |||f q$q|S )zCCollect variables and indexes to be merged from Coordinate objects.)r   rZ   r=   xindexesr[   r]   rn   )r   rT   coordsr=   r_   rH   rf   r5   r5   r6   collect_from_coordinatesy  s    r   r   )objectsrU   exclude_dimsrd   r>   c                   sn   t | } rBi }| D ]&\}} fdd|D }|r|||< qn|}t|||d\}	}
t|
t|	}
|	|
fS )zMerge variables/indexes from coordinates without automatic alignments.

    This function is used for merging coordinate from pre-existing xarray
    objects.
    c                   s$   g | ]\}}  |jr||fqS r5   )
isdisjointr@   re   r   r5   r6   rg     s   z3merge_coordinates_without_align.<locals>.<listcomp>rk   )r   r[   rp   r   rP   )r   rU   r   rd   	collectedfilteredrH   elementsZnew_elementsZmerged_coordsro   r5   r   r6   merge_coordinates_without_align  s"    
  
r   zIterable[DatasetLike]z#tuple[set[Hashable], set[Hashable]])rq   r>   c           	      C  s   ddl m} ddlm} t }t }| D ]b}t||rP||j ||j q(|	 D ]0\}}t||rXt|j
}|| || qXq(||fS )a  Given a list of dicts with xarray object values, identify coordinates.

    Parameters
    ----------
    list_of_mappings : list of dict or list of Dataset
        Of the same form as the arguments to expand_variable_dicts.

    Returns
    -------
    coord_names : set of variable names
    noncoord_names : set of variable names
        All variable found in the input should appear in either the set of
        coordinate or non-coordinate names.
    r   r   r!   )rx   r    ry   r"   rP   rz   updater   	data_varsr[   r{   discard)	rq   r    r"   coord_namesnoncoord_namesr   rH   rC   r   r5   r5   r6   determine_coords  s    



r   zIterable[CoercibleMapping])r   r>   c                 C  s   ddl m} ddlm} g }| D ]d}t||r4|}nFi }t|trNt| }| D ]"\}}t|trp||}|||< qV|| q |S )a  Convert pandas values found in a list of labeled objects.

    Parameters
    ----------
    objects : list of Dataset or mapping
        The mappings may contain any sort of objects coercible to
        xarray.Variables as keys, including pandas objects.

    Returns
    -------
    List of Dataset or dictionary objects. Any inputs or values in the inputs
    that were pandas objects have been converted into native xarray objects.
    r   r   r!   )	rx   r    ry   r"   rz   PANDAS_TYPESr}   r[   r]   )r   r    r"   rM   objr=   rX   vr5   r5   r6   coerce_pandas_values  s    



r   r,   z
int | Nonezdict[Hashable, MergeElement])r   priority_argrI   r>   c           	      C  sV   |dkri S t | | g}t||d\}}i }| D ]\}}|||f||< q6|S )aj  Extract the priority variable from a list of mappings.

    We need this method because in some cases the priority argument itself
    might have conflicting values (e.g., if it is a dict with two DataArray
    values with conflicting coordinate values).

    Parameters
    ----------
    objects : list of dict-like of Variable
        Dictionaries in which to find the priority variables.
    priority_arg : int or None
        Integer object whose variable should take priority.
    compat : {"identical", "equals", "broadcast_equals", "no_conflicts", "override"}, optional
        String indicating how to compare non-concatenated variables of the same name for
        potential conflicts. This is passed down to merge.

        - "broadcast_equals": all values must be equal when variables are
          broadcast against each other to ensure common dimensions.
        - "equals": all values and dimensions must be the same.
        - "identical": all values, dimensions and attributes must be the
          same.
        - "no_conflicts": only values which are not null in both datasets
          must be equal. The returned dataset then contains the combination
          of all non-null values.
        - "override": skip comparing and pick variable from first dataset

    Returns
    -------
    A dictionary of variables and associated indexes (if any) to prioritize.
    NrQ   )r   rp   r[   rn   )	r   r   rI   r   r=   r_   rT   rH   rf   r5   r5   r6   _get_priority_vars_and_indexes  s    #r   outerr%   zMapping[Any, Index] | Noneobject)r   rI   r^   r   r_   
fill_valuer>   c                 C  sV   t | t| }t||d||d}t||d}t|||d}	t||	|d\}
}|
|fS )zMerge coordinate variables.

    See merge_core below for argument descriptions. This works similarly to
    merge_core, except everything we don't worry about whether variables are
    coordinates or not.
    Fr^   r|   r_   r   r_   rQ   )rR   r   r   r   r   rp   )r   rI   r^   r   r_   r   coercedalignedr   rU   r=   out_indexesr5   r5   r6   merge_coords!  s        r   c                 C  s6   t || \}}| |g}| }t||||t||dS )zUsed in Dataset.__init__.)explicit_coordsr_   )_create_indexes_from_coordskeys
merge_corer   )r   r   rI   r^   r_   r   r   r5   r5   r6   merge_data_and_coords:  s    r   c           
        s   t  }|dk	r|| i }i } fdd| D }| D ]d\}}t||d}|j|fkrt||\}	|fdd|	D  ||	 ||	 q@|||< q@||fS )zsMaybe create default indexes from a mapping of coordinates.

    Return those indexes and updated coordinates.
    Nc                   s*   i | ]"\}}| ks t |tjr||qS r5   )rz   pdZ
MultiIndex)rW   rX   r   )r   r5   r6   rw   W  s
     z/_create_indexes_from_coords.<locals>.<dictcomp>rt   c                   s   i | ]
}| qS r5   r5   rV   ru   r5   r6   rw   b  s      )r}   r   r[   r   r@   r   )
r   r   Zall_variablesr_   Zupdated_coordsZ
index_varsrH   r   rf   r   r5   )r   rv   r6   r   H  s"    



r   c                 C  s6   |D ],}||kr| | j |fkrtd| dqdS )zValidate explicit coordinate names/dims.

    Raise a MergeError if an explicit coord shares a name with a dimension
    but is comprised of arbitrary dimensions.
    zcoordinate z shares a name with a dataset dimension, but is not a 1D variable along that dimension. This is disallowed by the xarray data model.N)r@   rG   )r=   r@   r   Z
coord_namer5   r5   r6   assert_valid_explicit_coordsk  s
    
r   c                   s  | sdS t |r|| |dS |dkr(i S |dkr<t| d S |dkrt| d | dd D ]T zt W q\ tk
r } z"tdt d	t  |W 5 d}~X Y q\X q\S |d
kr"i t | D ]N fdd  D   fdd D fdd D O qΈS |dkrzt| d | dd D ]0 t	 sDtdt dt  dqDS td| dS )zFCombine attributes from different variables according to combine_attrsN)contextZdropr0   r   r/   r&   zHcombine_attrs='no_conflicts', but some values are not the same. Merging z with Zdrop_conflictsc                   s&   i | ]\}}|kr| kr||qS r5   r5   rW   keyvalue)dropped_keysresultr5   r6   rw     s
     zmerge_attrs.<locals>.<dictcomp>c                   s,   i | ]$\}}| ks"t  | |r||qS r5   )r   r   ri   r5   r6   rw     s
     c                   s   h | ]}| kr|qS r5   r5   )rW   r   )r   r5   r6   	<setcomp>  s      zmerge_attrs.<locals>.<setcomp>r+   z6combine_attrs='identical', but attrs differ. First is z , other is .z%Unrecognised value for combine_attrs=)
callabler}   r   rB   rG   strrP   r   r[   r   )Zvariable_attrsrd   r   er5   )rj   r   r   r6   rm   z  sV    


rm   c                   @  s6   e Zd ZU ded< ded< ded< ded< d	ed
< dS )_MergeResultzdict[Hashable, Variable]r=   zset[Hashable]r   r<   r@   zdict[Hashable, Index]r_   zdict[Hashable, Any]rj   N)r8   r9   r:   __annotations__r5   r5   r5   r6   r     s
   
r   zSequence | None)	r   rI   r^   rd   r   r   r_   r   r>   c                   s  ddl m  ddlm t| t| }t||d||d}	t|	|d}
t|	||d}t	|
|||d\}}t
|}t|\}}|d	k	rt||| || | D ]\}}||kr|| q||}|rtd
| t fdd|D |}t|||||S )a  Core logic for merging labeled objects.

    This is not public API.

    Parameters
    ----------
    objects : list of mapping
        All values must be convertible to labeled arrays.
    compat : {"identical", "equals", "broadcast_equals", "no_conflicts", "override"}, optional
        Compatibility checks to use when merging variables.
    join : {"outer", "inner", "left", "right"}, optional
        How to combine objects with different indexes.
    combine_attrs : {"drop", "identical", "no_conflicts", "drop_conflicts",                      "override"} or callable, default: "override"
        How to combine attributes of objects
    priority_arg : int, optional
        Optional argument in `objects` that takes precedence over the others.
    explicit_coords : set, optional
        An explicit list of variables from `objects` that are coordinates.
    indexes : dict, optional
        Dictionary with values given by xarray.Index objects or anything that
        may be cast to pandas.Index objects.
    fill_value : scalar, optional
        Value to use for newly missing values

    Returns
    -------
    variables : dict
        Dictionary of Variable objects.
    coord_names : set
        Set of coordinate names.
    dims : dict
        Dictionary mapping from dimension names to sizes.
    attrs : dict
        Dictionary of attributes

    Raises
    ------
    MergeError if the merge cannot be done successfully.
    r   r   r!   Fr   r   rQ   )rI   rd   NzZunable to determine if these variables should be coordinates or not in the merged result: c                   s    g | ]}t | fr|jqS r5   )rz   rj   rl   r    r"   r5   r6   rg   
  s      zmerge_core.<locals>.<listcomp>)rx   r    ry   r"   rR   r   r   r   r   rp   r   r   r   r   r[   addintersectionrG   rm   r   )r   rI   r^   rd   r   r   r_   r   r   r   r   rU   r=   r   r@   r   r   rD   rE   Zambiguous_coordsrj   r5   r   r6   r     sJ    2       


r   r/   z&Iterable[DataArray | CoercibleMapping]r"   )r   rI   r^   r   rd   r>   c           
      C  s   ddl m} ddlm} g }| D ]@}t|||tfs<tdt||rR|jddn|}|| q t	|||||d}	|j
f |	 S )a   Merge any number of xarray objects into a single Dataset as variables.

    Parameters
    ----------
    objects : iterable of Dataset or iterable of DataArray or iterable of dict-like
        Merge together all variables from these objects. If any of them are
        DataArray objects, they must have a name.
    compat : {"identical", "equals", "broadcast_equals", "no_conflicts",               "override", "minimal"}, default: "no_conflicts"
        String indicating how to compare variables of the same name for
        potential conflicts:

        - "identical": all values, dimensions and attributes must be the
          same.
        - "equals": all values and dimensions must be the same.
        - "broadcast_equals": all values must be equal when variables are
          broadcast against each other to ensure common dimensions.
        - "no_conflicts": only values which are not null in both datasets
          must be equal. The returned dataset then contains the combination
          of all non-null values.
        - "override": skip comparing and pick variable from first dataset
        - "minimal": drop conflicting coordinates

    join : {"outer", "inner", "left", "right", "exact", "override"}, default: "outer"
        String indicating how to combine differing indexes in objects.

        - "outer": use the union of object indexes
        - "inner": use the intersection of object indexes
        - "left": use indexes from the first object with each dimension
        - "right": use indexes from the last object with each dimension
        - "exact": instead of aligning, raise `ValueError` when indexes to be
          aligned are not equal
        - "override": if indexes are of same size, rewrite indexes to be
          those of the first object with that dimension. Indexes for the same
          dimension must have the same size in all objects.

    fill_value : scalar or dict-like, optional
        Value to use for newly missing values. If a dict-like, maps
        variable names to fill values. Use a data array's name to
        refer to its values.
    combine_attrs : {"drop", "identical", "no_conflicts", "drop_conflicts",                      "override"} or callable, default: "override"
        A callable or a string indicating how to combine attrs of the objects being
        merged:

        - "drop": empty attrs on returned Dataset.
        - "identical": all attrs must be the same on every object.
        - "no_conflicts": attrs from all objects are combined, any that have
          the same name must also have the same value.
        - "drop_conflicts": attrs from all objects are combined, any that have
          the same name but different values are dropped.
        - "override": skip comparing and copy attrs from the first dataset to
          the result.

        If a callable, it must expect a sequence of ``attrs`` dicts and a context object
        as its only parameters.

    Returns
    -------
    Dataset
        Dataset with combined variables from each object.

    Examples
    --------
    >>> x = xr.DataArray(
    ...     [[1.0, 2.0], [3.0, 5.0]],
    ...     dims=("lat", "lon"),
    ...     coords={"lat": [35.0, 40.0], "lon": [100.0, 120.0]},
    ...     name="var1",
    ... )
    >>> y = xr.DataArray(
    ...     [[5.0, 6.0], [7.0, 8.0]],
    ...     dims=("lat", "lon"),
    ...     coords={"lat": [35.0, 42.0], "lon": [100.0, 150.0]},
    ...     name="var2",
    ... )
    >>> z = xr.DataArray(
    ...     [[0.0, 3.0], [4.0, 9.0]],
    ...     dims=("time", "lon"),
    ...     coords={"time": [30.0, 60.0], "lon": [100.0, 150.0]},
    ...     name="var3",
    ... )

    >>> x
    <xarray.DataArray 'var1' (lat: 2, lon: 2)>
    array([[1., 2.],
           [3., 5.]])
    Coordinates:
      * lat      (lat) float64 35.0 40.0
      * lon      (lon) float64 100.0 120.0

    >>> y
    <xarray.DataArray 'var2' (lat: 2, lon: 2)>
    array([[5., 6.],
           [7., 8.]])
    Coordinates:
      * lat      (lat) float64 35.0 42.0
      * lon      (lon) float64 100.0 150.0

    >>> z
    <xarray.DataArray 'var3' (time: 2, lon: 2)>
    array([[0., 3.],
           [4., 9.]])
    Coordinates:
      * time     (time) float64 30.0 60.0
      * lon      (lon) float64 100.0 150.0

    >>> xr.merge([x, y, z])
    <xarray.Dataset>
    Dimensions:  (lat: 3, lon: 3, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0 40.0 42.0
      * lon      (lon) float64 100.0 120.0 150.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0 2.0 nan 3.0 5.0 nan nan nan nan
        var2     (lat, lon) float64 5.0 nan 6.0 nan nan nan 7.0 nan 8.0
        var3     (time, lon) float64 0.0 nan 3.0 4.0 nan 9.0

    >>> xr.merge([x, y, z], compat="identical")
    <xarray.Dataset>
    Dimensions:  (lat: 3, lon: 3, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0 40.0 42.0
      * lon      (lon) float64 100.0 120.0 150.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0 2.0 nan 3.0 5.0 nan nan nan nan
        var2     (lat, lon) float64 5.0 nan 6.0 nan nan nan 7.0 nan 8.0
        var3     (time, lon) float64 0.0 nan 3.0 4.0 nan 9.0

    >>> xr.merge([x, y, z], compat="equals")
    <xarray.Dataset>
    Dimensions:  (lat: 3, lon: 3, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0 40.0 42.0
      * lon      (lon) float64 100.0 120.0 150.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0 2.0 nan 3.0 5.0 nan nan nan nan
        var2     (lat, lon) float64 5.0 nan 6.0 nan nan nan 7.0 nan 8.0
        var3     (time, lon) float64 0.0 nan 3.0 4.0 nan 9.0

    >>> xr.merge([x, y, z], compat="equals", fill_value=-999.0)
    <xarray.Dataset>
    Dimensions:  (lat: 3, lon: 3, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0 40.0 42.0
      * lon      (lon) float64 100.0 120.0 150.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0 2.0 -999.0 3.0 ... -999.0 -999.0 -999.0
        var2     (lat, lon) float64 5.0 -999.0 6.0 -999.0 ... -999.0 7.0 -999.0 8.0
        var3     (time, lon) float64 0.0 -999.0 3.0 4.0 -999.0 9.0

    >>> xr.merge([x, y, z], join="override")
    <xarray.Dataset>
    Dimensions:  (lat: 2, lon: 2, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0 40.0
      * lon      (lon) float64 100.0 120.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0 2.0 3.0 5.0
        var2     (lat, lon) float64 5.0 6.0 7.0 8.0
        var3     (time, lon) float64 0.0 3.0 4.0 9.0

    >>> xr.merge([x, y, z], join="inner")
    <xarray.Dataset>
    Dimensions:  (lat: 1, lon: 1, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0
      * lon      (lon) float64 100.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0
        var2     (lat, lon) float64 5.0
        var3     (time, lon) float64 0.0 4.0

    >>> xr.merge([x, y, z], compat="identical", join="inner")
    <xarray.Dataset>
    Dimensions:  (lat: 1, lon: 1, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0
      * lon      (lon) float64 100.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0
        var2     (lat, lon) float64 5.0
        var3     (time, lon) float64 0.0 4.0

    >>> xr.merge([x, y, z], compat="broadcast_equals", join="outer")
    <xarray.Dataset>
    Dimensions:  (lat: 3, lon: 3, time: 2)
    Coordinates:
      * lat      (lat) float64 35.0 40.0 42.0
      * lon      (lon) float64 100.0 120.0 150.0
      * time     (time) float64 30.0 60.0
    Data variables:
        var1     (lat, lon) float64 1.0 2.0 nan 3.0 5.0 nan nan nan nan
        var2     (lat, lon) float64 5.0 nan 6.0 nan nan nan 7.0 nan 8.0
        var3     (time, lon) float64 0.0 nan 3.0 4.0 nan 9.0

    >>> xr.merge([x, y, z], join="exact")
    Traceback (most recent call last):
    ...
    ValueError: cannot align objects with join='exact' where ...

    Raises
    ------
    xarray.MergeError
        If any variables with the same name have conflicting values.

    See also
    --------
    concat
    combine_nested
    combine_by_coords
    r   r   r!   zWobjects must be an iterable containing only Dataset(s), DataArray(s), and dictionaries.T)Zpromote_attrs)rd   r   )rx   r    ry   r"   rz   r}   	TypeErrorZ
to_datasetr]   r   Z_construct_direct_asdict)
r   rI   r^   r   rd   r    r"   Zdict_like_objectsr   Zmerge_resultr5   r5   r6   merge  s&     cr   CoercibleMappingzHashable | Iterable[Hashable]r   )datasetotheroverwrite_varsrI   r^   r   rd   r>   c                 C  s   t |trt |tst|}n|h}|s6| |g}d}n\|t|krP| |g}d}nBi }	i }
| D ]"\}}||krz||	|< q`||
|< q`| |
|	g}d}t||||||dS )z!Guts of the Dataset.merge method.Nr&   r'   )r   r   rd   )rz   r   r   rP   r[   r   )r   r   r   rI   r^   r   rd   objsr   Zother_overwriteZother_no_overwriterX   r   r5   r5   r6   dataset_merge_method  s2    



r   )r   r   r>   c                   s   ddl m} ddlm} t||snt|}| D ]:\}t|r2 fddjD }|r2|||< q2t	 |gd j
ddS )	zGuts of the Dataset.update method.

    This drops a duplicated coordinates from `other` if `other` is not an
    `xarray.Dataset`, e.g., if it's a dict with DataArray values (GH2068,
    GH2180).
    r   r   r!   c                   s$   g | ]}|j kr| jkr|qS r5   )r@   r   )rW   cr   r   r5   r6   rg   H  s   
 
z)dataset_update_method.<locals>.<listcomp>r&   r0   )r   r_   rd   )rx   r    ry   r"   rz   r}   r[   r   Z	drop_varsr   r   )r   r   r    r"   r   r   r5   r   r6   dataset_update_method9  s"    

r   )r-   N)Nr.   r0   N)N)r,   )r-   r   )N)N)W
__future__r   collectionsr   typingr   r   r   r   r   r	   r
   r   r   r   r   Zpandasr   Zxarray.corer   Zxarray.core.alignmentr   Zxarray.core.duck_array_opsr   Zxarray.core.indexesr   r   r   r   r   Zxarray.core.utilsr   r   r   r   Zxarray.core.variabler   r   r   Zxarray.core.coordinatesr   rx   r    ry   r"   Zxarray.core.typesr#   r$   r%   ZDimsLikeZ	ArrayLikeZVariableLikeZXarrayValueZDatasetLikeZSeriesZ	DataFrameZCoercibleValuer   r   rO   r1   rF   rB   rG   rN   rR   ZMergeElementrc   rp   r   r   	frozensetr   r   r   r   ZNAr   r   r   r   rm   r   r   r   r   r   r5   r5   r5   r6   <module>   s   4

  I"    q :$&$ 0

#
6
 [ {.