§
    !�’jöR  ã            
       óz  — d dl Z d dlZd dlZd dlZddlmZ d dlZd dlZd dlZd dl	Z	ddlm
Z
mZmZmZmZ g d¢Ze j        ded         f         Ze j        eeegeeef         f         Zd„ Zd	„ Zd
„ Zd„ Zd„ Z ej        ee¦  «          ej        ej        e¦  «          ej        ee¦  «          ej        ee¦  «         d„ Zej        d„ ¦   «         Zej        d„ ¦   «         Zd„ Z	 d(dededede j        dz  fd„Z d)d„Z!d„ Z"d„ Z#d)ddœd„Z$d„ Z%d*d„Z& G d„ d ¦  «        Z'd!„ Z(d"„ Z)d#„ Z*d$„ Z+ddd%œd&„Z,ddd%œd'„Z-dS )+é    Né   )Ú_uarray)ÚBackendNotImplementedErrorÚ	_FunctionÚ_SkipBackendContextÚ_SetBackendContextÚ_BackendState)Úset_backendÚset_global_backendÚskip_backendÚregister_backendÚdetermine_backendÚdetermine_backend_multiÚclear_backendsÚcreate_multimethodÚgenerate_multimethodr   r   ÚDispatchableÚwrap_single_convertorÚwrap_single_convertor_instanceÚall_of_typeÚmark_asÚ	set_stateÚ	get_stateÚreset_stater	   r   r   .)r   .c                 ó  — dd l }	 |                     | ¦  «        }|                     d¦  «        }|}|D ]}t          ||¦  «        }Œ|�t	          j        ||¦  «        }|S # t          t          f$ r}ddlm	} ||‚d }~ww xY w)Nr   ú.)ÚUnpicklingError)
Ú	importlibÚimport_moduleÚsplitÚgetattrÚtypesÚ
MethodTypeÚImportErrorÚAttributeErrorÚpickler   )	Úmod_nameÚqnameÚself_r   ÚmoduleÚfuncÚqÚer   s	            úIC:\Projects\DSCons\.venv\Lib\site-packages\scipy\_lib\_uarray\_backend.pyÚunpickle_functionr/   1   s·   € ØÐÐÐð%Ø×(Ò(¨Ñ2Ô2ˆØ—’˜CÑ Ô ˆØˆØð 	$ð 	$ˆAÝ˜4 Ñ#Ô#ˆDˆDàÐÝÔ# D¨%Ñ0Ô0ˆDàˆøÝ�Ð(ð %ð %ð %Ø*Ð*Ð*Ð*Ð*Ð*à 1Ð$øøøøð%øøøs   †AA  Á A?Á1	A:Á:A?c                 ó  — t          | dd ¦  «        }t          | dd ¦  «        }t          | dd ¦  «        }	 t          |||¦  «        }n# t          j        $ r d }Y nw xY w|| urt          j        d| › d|› �¦  «        ‚t          |||ffS )NÚ
__module__Ú__qualname__Ú__self__zCan't pickle z: it's not the same object as )r!   r/   r&   r   ÚPicklingError)r+   r'   r(   r)   Útests        r.   Úpickle_functionr6   E   s½   € Ý�t˜\¨4Ñ0Ô0€HÝ�D˜.¨$Ñ/Ô/€EÝ�D˜* dÑ+Ô+€EðÝ  ¨5°%Ñ8Ô8ˆˆøÝÔ!ð ð ð Øˆˆˆðøøøð �4ÐÐÝÔ"ØF˜DÐFÐFÀÐFÐFñ
ô 
ð 	
õ ˜x¨°Ð6Ð6Ð6s   µA ÁAÁAc                 óL   — t           j        j        |                      ¦   «         fS ©N)r   r	   Ú	_unpickleÚ_pickle)Ústates    r.   Úpickle_stater<   W   s   € ÝÔ Ô*¨E¯MªM©O¬OÐ;Ð;ó    c                 ó8   — t           |                      ¦   «         fS r8   )r   r:   ©Úctxs    r.   Úpickle_set_backend_contextrA   [   s   € Ý˜sŸ{š{™}œ}Ð,Ð,r=   c                 ó8   — t           |                      ¦   «         fS r8   )r   r:   r?   s    r.   Úpickle_skip_backend_contextrC   _   s   € Ý §¢¡¤Ð-Ð-r=   c                  ó(   — t          j        ¦   «         S )zï
    Returns an opaque object containing the current state of all the backends.

    Can be used for synchronization between threads/processes.

    See Also
    --------
    set_state
        Sets the state returned by this function.
    )r   r   © r=   r.   r   r   i   s   € õ ÔÑÔÐr=   c               #   óz   K  — t          t          ¦   «         ¦  «        5  dV — ddd¦  «         dS # 1 swxY w Y   dS )zê
    Returns a context manager that resets all state once exited.

    See Also
    --------
    set_state
        Context manager that sets the backend state.
    get_state
        Gets a state to be set by this context manager.
    N)r   r   rE   r=   r.   r   r   w   s‡   è è € õ 
•9‘;”;Ñ	Ô	ð ð Øˆˆˆðð ð ñ ô ð ð ð ð ð ð ð øøøð ð ð ð ð ð s   ž0°4·4c              #   ó¶   K  — t          ¦   «         }t          j        | ¦  «         	 dV — t          j        |d¦  «         dS # t          j        |d¦  «         w xY w)zÅ
    A context manager that sets the state of the backends to one returned by :obj:`get_state`.

    See Also
    --------
    get_state
        Gets a state to be set by this context manager.
    NT)r   r   r   )r;   Ú	old_states     r.   r   r   ‡   sb   è è € õ ‘”€IÝÔ�eÑÔÐð+ØˆˆˆåÔ˜) TÑ*Ô*Ð*Ð*Ð*ø�Ô˜) TÑ*Ô*Ð*Ð*øøøs   ¦A ÁAc                  ó   ‡ ‡— ˆ ˆfd„}|S )au  
    Creates a decorator for generating multimethods.

    This function creates a decorator that can be used with an argument
    extractor in order to generate a multimethod. Other than for the
    argument extractor, all arguments are passed on to
    :obj:`generate_multimethod`.

    See Also
    --------
    generate_multimethod
        Generates a multimethod.
    c                 ó$   •— t          | g‰¢R i ‰¤ŽS r8   )r   )ÚaÚargsÚkwargss    €€r.   Úwrapperz#create_multimethod.<locals>.wrapper¨   s!   ø€ Ý# AÐ7¨Ð7Ð7Ð7°Ð7Ð7Ð7r=   rE   )rL   rM   rN   s   `` r.   r   r   ™   s)   øø€ ð8ð 8ð 8ð 8ð 8ð 8ð €Nr=   Úargument_extractorÚargument_replacerÚdomainÚdefaultc                 óz   — t          | ¦  «        \  }}}t          | |||||¦  «        }t          j        || ¦  «        S )aß  
    Generates a multimethod.

    Parameters
    ----------
    argument_extractor : ArgumentExtractorType
        A callable which extracts the dispatchable arguments. Extracted arguments
        should be marked by the :obj:`Dispatchable` class. It has the same signature
        as the desired multimethod.
    argument_replacer : ArgumentReplacerType
        A callable with the signature (args, kwargs, dispatchables), which should also
        return an (args, kwargs) pair with the dispatchables replaced inside the
        args/kwargs.
    domain : str
        A string value indicating the domain of this multimethod.
    default: Optional[Callable], optional
        The default implementation of this multimethod, where ``None`` (the default)
        specifies there is no default implementation.

    Examples
    --------
    In this example, ``a`` is to be dispatched over, so we return it, while marking it
    as an ``int``.
    The trailing comma is needed because the args have to be returned as an iterable.

    >>> def override_me(a, b):
    ...   return Dispatchable(a, int),

    Next, we define the argument replacer that replaces the dispatchables inside
    args/kwargs with the supplied ones.

    >>> def override_replacer(args, kwargs, dispatchables):
    ...     return (dispatchables[0], args[1]), {}

    Next, we define the multimethod.

    >>> overridden_me = generate_multimethod(
    ...     override_me, override_replacer, "ua_examples"
    ... )

    Notice that there's no default implementation, unless you supply one.

    >>> overridden_me(1, "a")
    Traceback (most recent call last):
        ...
    uarray.BackendNotImplementedError: ...

    >>> overridden_me2 = generate_multimethod(
    ...     override_me, override_replacer, "ua_examples", default=lambda x, y: (x, y)
    ... )
    >>> overridden_me2(1, "a")
    (1, 'a')

    See Also
    --------
    uarray
        See the module documentation for how to override the method by creating
        backends.
    )Úget_defaultsr   Ú	functoolsÚupdate_wrapper)rO   rP   rQ   rR   Úkw_defaultsÚarg_defaultsÚoptsÚua_funcs           r.   r   r   ®   sQ   € õB '3Ð3EÑ&FÔ&FÑ#€K�˜tÝØØØØØØñô €Gõ Ô# GÐ-?Ñ@Ô@Ð@r=   Fc                 óÒ   — t          j        ¦   «         }	 | j        |d||f         S # t          $ r
 i | _        Y nt          $ r Y nw xY wt          | ||¦  «        }|| j        |d||f<   |S )aÌ  
    A context manager that sets the preferred backend.

    Parameters
    ----------
    backend
        The backend to set.
    coerce
        Whether or not to coerce to a specific backend's types. Implies ``only``.
    only
        Whether or not this should be the last backend to try.

    See Also
    --------
    skip_backend: A context manager that allows skipping of backends.
    set_global_backend: Set a single, global backend for a domain.
    Úset)Ú	threadingÚget_native_idÚ__ua_cache__r%   ÚKeyErrorr   )ÚbackendÚcoerceÚonlyÚtidr@   s        r.   r
   r
   ü   sœ   € õ$ Ô
!Ñ
#Ô
#€CðØÔ# C¨°¸Ð$<Ô=Ð=øÝð "ð "ð "Ø!ˆÔÐÐÝð ð ð Øˆðøøøõ ˜W f¨dÑ
3Ô
3€CØ58€GÔ˜˜e V¨TÐ1Ñ2Ø€Js   •& ¦A¹	AÁAc                 óÆ   — t          j        ¦   «         }	 | j        |df         S # t          $ r
 i | _        Y nt          $ r Y nw xY wt          | ¦  «        }|| j        |df<   |S )a·  
    A context manager that allows one to skip a given backend from processing
    entirely. This allows one to use another backend's code in a library that
    is also a consumer of the same backend.

    Parameters
    ----------
    backend
        The backend to skip.

    See Also
    --------
    set_backend: A context manager that allows setting of backends.
    set_global_backend: Set a single, global backend for a domain.
    Úskip)r]   r^   r_   r%   r`   r   )ra   rd   r@   s      r.   r   r     sŽ   € õ  Ô
!Ñ
#Ô
#€CðØÔ# C¨ KÔ0Ð0øÝð "ð "ð "Ø!ˆÔÐÐÝð ð ð Øˆðøøøõ ˜gÑ
&Ô
&€CØ(+€GÔ˜˜f˜Ñ%Ø€Js   •$ ¤A·	AÁAc                 ó¤  — t          j        | ¦  «        }i }g }t          ¦   «         }|j                             ¦   «         D ]\  }}|j        t           j        j        ur
|j        ||<   |j        t           j        j	        t           j        j
        fv r|                     |j        ¦  «         |                     |¦  «         Œ€|t          |¦  «        |fS r8   )ÚinspectÚ	signaturer\   Ú
parametersÚitemsrR   Ú	ParameterÚemptyÚkindÚPOSITIONAL_ONLYÚPOSITIONAL_OR_KEYWORDÚappendÚaddÚtuple)ÚfÚsigrW   rX   rY   ÚkÚvs          r.   rT   rT   8  sÈ   € Ý
Ô
˜AÑ
Ô
€CØ€KØ€LÝ‰5Œ5€DØ”×$Ò$Ñ&Ô&ð ð ‰ˆˆ1ØŒ9�GÔ-Ô3Ð3Ð3ØœYˆK˜‰NØŒ6ÝÔÔ-ÝÔÔ3ð
ð 
ð 
ð ×Ò ¤	Ñ*Ô*Ð*Ø�Š�‰Œˆˆà�˜lÑ+Ô+¨TÐ1Ð1r=   )Útry_lastc                ó4   — t          j        | |||¦  «         dS )ae  
    This utility method replaces the default backend for permanent use. It
    will be tried in the list of backends automatically, unless the
    ``only`` flag is set on a backend. This will be the first tried
    backend outside the :obj:`set_backend` context manager.

    Note that this method is not thread-safe.

    .. warning::
        We caution library authors against using this function in
        their code. We do *not* support this use-case. This function
        is meant to be used only by users themselves, or by a reference
        implementation, if one exists.

    Parameters
    ----------
    backend
        The backend to register.
    coerce : bool
        Whether to coerce input types when trying this backend.
    only : bool
        If ``True``, no more backends will be tried if this fails.
        Implied by ``coerce=True``.
    try_last : bool
        If ``True``, the global backend is tried after registered backends.

    See Also
    --------
    set_backend: A context manager that allows setting of backends.
    skip_backend: A context manager that allows skipping of backends.
    N)r   r   )ra   rb   rc   rx   s       r.   r   r   J  s"   € õ@ Ô˜w¨°°hÑ?Ô?Ð?Ð?Ð?r=   c                 ó.   — t          j        | ¦  «         dS )a0  
    This utility method sets registers backend for permanent use. It
    will be tried in the list of backends automatically, unless the
    ``only`` flag is set on a backend.

    Note that this method is not thread-safe.

    Parameters
    ----------
    backend
        The backend to register.
    N)r   r   )ra   s    r.   r   r   m  s   € õ Ô˜WÑ%Ô%Ð%Ð%Ð%r=   Tc                 ó2   — t          j        | ||¦  «         dS )al  
    This utility method clears registered backends.

    .. warning::
        We caution library authors against using this function in
        their code. We do *not* support this use-case. This function
        is meant to be used only by users themselves.

    .. warning::
        Do NOT use this method inside a multimethod call, or the
        program is likely to crash.

    Parameters
    ----------
    domain : Optional[str]
        The domain for which to de-register backends. ``None`` means
        de-register for all domains.
    registered : bool
        Whether or not to clear registered backends. See :obj:`register_backend`.
    globals : bool
        Whether or not to clear global backends. See :obj:`set_global_backend`.

    See Also
    --------
    register_backend : Register a backend globally.
    set_global_backend : Set a global backend.
    N)r   r   )rQ   Ú
registeredÚglobalss      r.   r   r   }  s   € õ8 Ô˜6 :¨wÑ7Ô7Ð7Ð7Ð7r=   c                   ó*   — e Zd ZdZdd„Zd„ Zd„ ZeZdS )r   aý  
    A utility class which marks an argument with a specific dispatch type.


    Attributes
    ----------
    value
        The value of the Dispatchable.

    type
        The type of the Dispatchable.

    Examples
    --------
    >>> x = Dispatchable(1, str)
    >>> x
    <Dispatchable: type=<class 'str'>, value=1>

    See Also
    --------
    all_of_type
        Marks all unmarked parameters of a function.

    mark_as
        Allows one to create a utility function to mark as a given type.
    Tc                 ó0   — || _         || _        || _        d S r8   )ÚvalueÚtypeÚ	coercible)Úselfr€   Údispatch_typer‚   s       r.   Ú__init__zDispatchable.__init__¸  s   € ØˆŒ
Ø!ˆŒ	Ø"ˆŒˆˆr=   c                 ó*   — | j         | j        f|         S r8   )r�   r€   )rƒ   Úindexs     r.   Ú__getitem__zDispatchable.__getitem__½  s   € Ø”	˜4œ:Ð& uÔ-Ð-r=   c                 óR   — dt          | ¦  «        j        › d| j         ›d| j        ›d�S )Nú<z: type=z, value=ú>)r�   Ú__name__r€   )rƒ   s    r.   Ú__str__zDispatchable.__str__À  s0   € ØS•4˜‘:”:Ô&ÐSÐS¨t¬yÐSÐSÀDÄJÐSÐSÐSÐSr=   N)T)rŒ   r1   r2   Ú__doc__r…   rˆ   r�   Ú__repr__rE   r=   r.   r   r   œ  sT   € € € € € ðð ð6#ð #ð #ð #ð
.ð .ð .ðTð Tð Tð €H€H€Hr=   r   c                 ó8   — t          j        t          | ¬¦  «        S )zÉ
    Creates a utility function to mark something as a specific type.

    Examples
    --------
    >>> mark_int = mark_as(int)
    >>> mark_int(1)
    <Dispatchable: type=<class 'int'>, value=1>
    ©r„   )rU   Úpartialr   r‘   s    r.   r   r   Æ  s   € õ Ô�\¸ÐGÑGÔGÐGr=   c                 ó   ‡ — ˆ fd„}|S )a$  
    Marks all unmarked arguments as a given type.

    Examples
    --------
    >>> @all_of_type(str)
    ... def f(a, b):
    ...     return a, Dispatchable(b, int)
    >>> f('a', 1)
    (<Dispatchable: type=<class 'str'>, value='a'>,
     <Dispatchable: type=<class 'int'>, value=1>)
    c                 óJ   •‡ — t          j        ‰ ¦  «        ˆˆ fd„¦   «         }|S )Nc                  óJ   •—  ‰| i |¤Ž}t          ˆfd„|D ¦   «         ¦  «        S )Nc              3   óf   •K  — | ]+}t          |t          ¦  «        st          |‰¦  «        n|V — Œ,d S r8   ©Ú
isinstancer   )Ú.0ÚargÚarg_types     €r.   ú	<genexpr>z<all_of_type.<locals>.outer.<locals>.inner.<locals>.<genexpr>å  sZ   øè è € ð ð ð õ " #¥|Ñ4Ô4ð•˜S (Ñ+Ô+Ð+àðð ð ð ð ð r=   )rs   )rL   rM   Úextracted_argsr›   r+   s      €€r.   Úinnerz)all_of_type.<locals>.outer.<locals>.innerâ  sQ   ø€ à!˜T 4Ð2¨6Ð2Ð2ˆNÝð ð ð ð ð *ð	ñ ô ñ ô ð r=   ©rU   Úwraps)r+   rž   r›   s   ` €r.   Úouterzall_of_type.<locals>.outerá  s>   øø€ Ý	Œ˜Ñ	Ô	ð	ð 	ð 	ð 	ð 	ñ 
Ô	ð	ð ˆr=   rE   )r›   r¡   s   ` r.   r   r   Ó  s#   ø€ ðð ð ð ð ð €Lr=   c                 óF   ‡ — t          j        ‰ ¦  «        ˆ fd„¦   «         }|S )úá
    Wraps a ``__ua_convert__`` defined for a single element to all elements.
    If any of them return ``NotImplemented``, the operation is assumed to be
    undefined.

    Accepts a signature of (value, type, coerce).
    c                 ó    •— g }| D ]G} ‰|j         |j        |o|j        ¦  «        }|t          u r	t          c S |                     |¦  «         ŒH|S r8   ©r€   r�   r‚   ÚNotImplementedrq   )Údispatchablesrb   Ú	convertedÚdÚcÚconvert_singles        €r.   Ú__ua_convert__z-wrap_single_convertor.<locals>.__ua_convert__ú  si   ø€ àˆ	Øð 	 ð 	 ˆAØ�˜qœw¨¬°Ð0F¸1¼;ÑGÔGˆAà•NÐ"Ð"Ý%Ð%Ð%Ð%à×Ò˜QÑÔÐÐàÐr=   rŸ   ©r«   r¬   s   ` r.   r   r   ñ  ó;   ø€ õ „_�^Ñ$Ô$ð
ð 
ð 
ð 
ñ %Ô$ð
ð Ðr=   c                 óF   ‡ — t          j        ‰ ¦  «        ˆ fd„¦   «         }|S )r£   c                 ó¢   •— g }|D ]H} ‰| |j         |j        |o|j        ¦  «        }|t          u r	t          c S |                     |¦  «         ŒI|S r8   r¥   )rƒ   r§   rb   r¨   r©   rª   r«   s         €r.   r¬   z6wrap_single_convertor_instance.<locals>.__ua_convert__  sk   ø€ àˆ	Øð 	 ð 	 ˆAØ�˜t Q¤W¨a¬f°fÐ6LÀÄÑMÔMˆAà•NÐ"Ð"Ý%Ð%Ð%Ð%à×Ò˜QÑÔÐÐàÐr=   rŸ   r­   s   ` r.   r   r   
  r®   r=   )rc   rb   c                óv   — t          | ||¦  «        f}t          j        |||¦  «        }t          |||¬¦  «        S )a	  Set the backend to the first active backend that supports ``value``

    This is useful for functions that call multimethods without any dispatchable
    arguments. You can use :func:`determine_backend` to ensure the same backend
    is used everywhere in a block of multimethod calls.

    Parameters
    ----------
    value
        The value being tested
    dispatch_type
        The dispatch type associated with ``value``, aka
        ":ref:`marking <MarkingGlossary>`".
    domain: string
        The domain to query for backends and set.
    coerce: bool
        Whether or not to allow coercion to the backend's types. Implies ``only``.
    only: bool
        Whether or not this should be the last backend to try.

    See Also
    --------
    set_backend: For when you know which backend to set

    Notes
    -----

    Support is determined by the ``__ua_convert__`` protocol. Backends not
    supporting the type must return ``NotImplemented`` from their
    ``__ua_convert__`` if they don't support input of that type.

    Examples
    --------

    Suppose we have two backends ``BackendA`` and ``BackendB`` each supporting
    different types, ``TypeA`` and ``TypeB``. Neither supporting the other type:

    >>> with ua.set_backend(ex.BackendA):
    ...     ex.call_multimethod(ex.TypeB(), ex.TypeB())
    Traceback (most recent call last):
        ...
    uarray.BackendNotImplementedError: ...

    Now consider a multimethod that creates a new object of ``TypeA``, or
    ``TypeB`` depending on the active backend.

    >>> with ua.set_backend(ex.BackendA), ua.set_backend(ex.BackendB):
    ...         res = ex.creation_multimethod()
    ...         ex.call_multimethod(res, ex.TypeA())
    Traceback (most recent call last):
        ...
    uarray.BackendNotImplementedError: ...

    ``res`` is an object of ``TypeB`` because ``BackendB`` is set in the
    innermost with statement. So, ``call_multimethod`` fails since the types
    don't match.

    Instead, we need to first find a backend suitable for all of our objects.

    >>> with ua.set_backend(ex.BackendA), ua.set_backend(ex.BackendB):
    ...     x = ex.TypeA()
    ...     with ua.determine_backend(x, "mark", domain="ua_examples"):
    ...         res = ex.creation_multimethod()
    ...         ex.call_multimethod(res, x)
    TypeA

    ©rb   rc   )r   r   r   r
   )r€   r„   rQ   rc   rb   r§   ra   s          r.   r   r   #  sB   € õH " %¨¸Ñ?Ô?ÐA€MÝÔ'¨°¸vÑFÔF€Gå�w v°DÐ9Ñ9Ô9Ð9r=   c                óv  ‡— d|v r1|                      d¦  «        Št          ˆfd„| D ¦   «         ¦  «        } n7t          | ¦  «        } t          d„ | D ¦   «         ¦  «        st          d¦  «        ‚t	          |¦  «        dk    rt          d|› �¦  «        ‚t          j        || |¦  «        }t          |||¬¦  «        S )aé	  Set a backend supporting all ``dispatchables``

    This is useful for functions that call multimethods without any dispatchable
    arguments. You can use :func:`determine_backend_multi` to ensure the same
    backend is used everywhere in a block of multimethod calls involving
    multiple arrays.

    Parameters
    ----------
    dispatchables: Sequence[Union[uarray.Dispatchable, Any]]
        The dispatchables that must be supported
    domain: string
        The domain to query for backends and set.
    coerce: bool
        Whether or not to allow coercion to the backend's types. Implies ``only``.
    only: bool
        Whether or not this should be the last backend to try.
    dispatch_type: Optional[Any]
        The default dispatch type associated with ``dispatchables``, aka
        ":ref:`marking <MarkingGlossary>`".

    See Also
    --------
    determine_backend: For a single dispatch value
    set_backend: For when you know which backend to set

    Notes
    -----

    Support is determined by the ``__ua_convert__`` protocol. Backends not
    supporting the type must return ``NotImplemented`` from their
    ``__ua_convert__`` if they don't support input of that type.

    Examples
    --------

    :func:`determine_backend` allows the backend to be set from a single
    object. :func:`determine_backend_multi` allows multiple objects to be
    checked simultaneously for support in the backend. Suppose we have a
    ``BackendAB`` which supports ``TypeA`` and ``TypeB`` in the same call,
    and a ``BackendBC`` that doesn't support ``TypeA``.

    >>> with ua.set_backend(ex.BackendAB), ua.set_backend(ex.BackendBC):
    ...     a, b = ex.TypeA(), ex.TypeB()
    ...     with ua.determine_backend_multi(
    ...         [ua.Dispatchable(a, "mark"), ua.Dispatchable(b, "mark")],
    ...         domain="ua_examples"
    ...     ):
    ...         res = ex.creation_multimethod()
    ...         ex.call_multimethod(res, a, b)
    TypeA

    This won't call ``BackendBC`` because it doesn't support ``TypeA``.

    We can also use leave out the ``ua.Dispatchable`` if we specify the
    default ``dispatch_type`` for the ``dispatchables`` argument.

    >>> with ua.set_backend(ex.BackendAB), ua.set_backend(ex.BackendBC):
    ...     a, b = ex.TypeA(), ex.TypeB()
    ...     with ua.determine_backend_multi(
    ...         [a, b], dispatch_type="mark", domain="ua_examples"
    ...     ):
    ...         res = ex.creation_multimethod()
    ...         ex.call_multimethod(res, a, b)
    TypeA

    r„   c              3   óf   •K  — | ]+}t          |t          ¦  «        r|nt          |‰¦  «        V — Œ,d S r8   r—   )r™   r©   Ú	disp_types     €r.   rœ   z*determine_backend_multi.<locals>.<genexpr>µ  sT   øè è € ð 
ð 
àõ ˜A�|Ñ,Ô,ÐLˆAˆAµ,¸qÀ)Ñ2LÔ2Lð
ð 
ð 
ð 
ð 
ð 
r=   c              3   ó@   K  — | ]}t          |t          ¦  «        V — Œd S r8   r—   )r™   r©   s     r.   rœ   z*determine_backend_multi.<locals>.<genexpr>»  s,   è è € ÐFÐF°1•:˜a¥Ñ.Ô.ÐFÐFÐFÐFÐFÐFr=   z6dispatchables must be instances of uarray.Dispatchabler   z'Received unexpected keyword arguments: r²   )Úpoprs   ÚallÚ	TypeErrorÚlenr   r   r
   )r§   rQ   rc   rb   rM   ra   rµ   s         @r.   r   r   m  sè   ø€ ðL ˜&Ð Ð Ø—J’J˜Ñ/Ô/ˆ	Ýð 
ð 
ð 
ð 
à"ð
ñ 
ô 
ñ 
ô 
ˆˆõ
 ˜mÑ,Ô,ˆÝÐFÐF¸ÐFÑFÔFÑFÔFð 	VÝÐTÑUÔUÐUå
ˆ6�{„{�aÒÐÝÐJÀ&ÐJÐJÑKÔKÐKåÔ'¨°¸vÑFÔF€Gå�w v°DÐ9Ñ9Ô9Ð9r=   r8   )FF)TF).Útypingr"   rh   rU   Ú r   Úcopyregr&   Ú
contextlibr]   r   r   r   r   r	   Ú__all__ÚCallablers   ÚArgumentExtractorTypeÚdictÚArgumentReplacerTyper/   r6   r<   rA   rC   r   Úcontextmanagerr   r   r   Ústrr   r
   r   rT   r   r   r   r   r   r   r   r   r   r   rE   r=   r.   ú<module>rÆ      s–  ðØ €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð €ð2 œ¨¨UÐ3FÔ-GÐ(GÔHÐ Ø”Ø
ˆD�%Ð˜%  t Ô,Ð,ôÐ ð%ð %ð %ð(7ð 7ð 7ð$<ð <ð <ð-ð -ð -ð.ð .ð .ð €„ˆy˜/Ñ *Ô *Ð *Ø €„ˆwÔ$ lÑ 3Ô 3Ð 3Ø €„Ð!Ð#=Ñ >Ô >Ð >Ø €„Ð"Ð$?Ñ @Ô @Ð @ðð ð ð Ôðð ñ Ôðð Ôð+ð +ñ Ôð+ð"ð ð ð2 '+ð	KAð KAØ-ðKAà+ðKAð ðKAð Œ_˜tÑ#ð	KAð KAð KAð KAð\ð ð ð ð>ð ð ð:2ð 2ð 2ð$ @Àeð  @ð  @ð  @ð  @ð  @ðF&ð &ð &ð 8ð 8ð 8ð 8ð>'ð 'ð 'ð 'ð 'ñ 'ô 'ð 'ðT
Hð 
Hð 
Hðð ð ð<ð ð ð2ð ð ð2 =AÈð G:ð G:ð G:ð G:ð G:ðV $(°ðV:ð V:ð V:ð V:ð V:ð V:ð V:r=   