o
    CipJ                  	   @   s  d dl Z d dlmZ d dlmZmZmZmZmZm	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 d dlmZmZ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(m)Z)m*Z* d d
l+m,Z, d dl-m.Z. d dl/m0Z1 G dd deZ2G dd de2Z3dededeeeef fddZ4dedefddZ5dedeeef fddZ6dedefddZ7dedefddZ8	d%dede9defd d!Z:d"e;dee fd#d$Z<dS )&    N)partial)CallableListOptionalSequenceTuplecast)Literal)Type)message_registry)PluginFunctionContextMethodContextCheckerPluginInterface)ARG_POSARG_STARTypeInfoContextFuncDefStrExprIntExpr
Expression)r
   CallableTypeNoneTyp
OverloadedTypeVarLikeTypeTypeVarTypeInstance	UnionTypeUninhabitedTypeAnyType	TypeOfAnyget_proper_typeget_proper_types)make_simplified_union)TypeChecker)parsec                   @   s,   e Zd Zdedeeegef  fddZdS )
TrioPluginfullnamereturnc                 C   s4   |dkrt S |dkrtS |dkrtS |dkrtS d S )N#trio_typing.takes_callable_and_argszasync_generator.async_generatorzasync_generator.yield_zasync_generator.yield_from_) takes_callable_and_args_callbackasync_generator_callbackyield_callbackyield_from_callbackselfr(    r1   E/home/kuhnn/.local/lib/python3.10/site-packages/trio_typing/plugin.pyget_function_hook'   s   zTrioPlugin.get_function_hookN)	__name__
__module____qualname__strr   r   r   r
   r3   r1   r1   r1   r2   r'   &   s    r'   c                       s4   e Zd Zdedeeegef  f fddZ  Z	S )TrioPlugin13r(   r)   c                    s    |dkr
t tddS t |S )Nr*   F)has_type_var_default)r   r+   superr3   r/   	__class__r1   r2   r3   6   s   zTrioPlugin13.get_function_hook)
r4   r5   r6   r7   r   r   r   r
   r3   __classcell__r1   r1   r;   r2   r8   5   s    r8   ctxoriginal_async_return_typer)   c           
   
   C   s  g }t |}t|tr|j}n|g}d}d}g }zY|D ]T}t |}t|trj|jjdkrEt|jdkr7t	d|dur?t	d|jd }q|jjdkrdt|jdkrVt	d|dur^t	d	|jd }q|
| q|
| qW n( t	y }	 z| jd
|	| j ttjttj|fW  Y d}	~	S d}	~	ww |du r|du rttjttj|fS |du rt| jj| jj}|du rt| jj| jj}|s||td| jj| jjdfS ||t|| jj| jjfS )a  Return the yield type, send type, and return type of
    an @async_generator decorated function that was
    originally declared to return ``original_async_return_type``.

    This tries to interpret ``original_async_return_type`` as a union
    between the async generator return type (i.e., the thing actually
    returned by the decorated function, which becomes the value
    associated with a ``StopAsyncIteration`` exception), an optional
    ``trio_typing.YieldType[X]`` where ``X`` is the type of values
    that the async generator yields, and an optional
    ``trio_typing.SendType[Y]`` where ``Y`` is the type of values that
    the async generator expects to be sent. If one of ``YieldType``
    and ``SendType`` is specified, the other is assumed to be None;
    if neither is specified, both are assumed to be Any.
    If ``original_async_return_type`` includes a ``YieldType``
    and/or a ``SendType`` but no actual return type, the return
    is inferred as ``NoReturn``.
    Nztrio_typing.YieldType   z YieldType must take one argumentz"YieldType specified multiple timesr   ztrio_typing.SendTypezSendType must take one argumentz!SendType specified multiple timesz(invalid @async_generator return type: {}T)is_noreturnlinecolumn)r"   
isinstancer   itemsr   typer(   lenargs
ValueErrorappendapifailformatcontextr    r!   
from_errorunannotatedr   rB   rC   r   r$   )
r>   r?   armsresolved_async_return_type
yield_type	send_type
other_armsorig_armarmexr1   r1   r2   "decode_agen_types_from_return_type?   sn   

	rY   c                 C   sj   | j }t|ts
|S t|j}t|tr3|jjdkr3t|j	dkr3|j
|j
tt| |j	d ddS |S )aP  Handle @async_generator.

    This moves the yield type and send type declarations from
    the return type of the decorated function to the appropriate
    type parameters of ``trio_typing.CompatAsyncGenerator``.
    That is, if you say::

        @async_generator
        async def example() -> Union[str, YieldType[bool], SendType[int]]:
            ...

    then the decorated ``example()`` will return values of type
    ``CompatAsyncGenerator[bool, int, str]``, as opposed to
    ``CompatAsyncGenerator[Any, Any, Union[str,
    YieldType[bool], SendType[int]]`` without the plugin.
     trio_typing.CompatAsyncGenerator      )rH   )ret_type)default_return_typerD   r   r"   r]   r   rF   r(   rG   rH   copy_modifiedlistrY   )r>   decorator_return_typeagen_return_typer1   r1   r2   r,      s    

r,   c                 C   s   t t| j}|j }|du st|tr|jr|js,| j	d| j
 ttjttjfS t|jtr[t|jjtr[|jjjjdkr[t|jjjdkr[t| |jjjd \}}}||fS ttjttjfS )zReturn the yield and send types that would be returned by
    decode_agen_types_from_return_type() for the function that's
    currently being typechecked, i.e., the function that contains the
    call described in ``ctx``.
    Nz9async_generator.yield_() outside an @async_generator funcztyping.Coroutiner[   r\   )r   r%   rK   scopetop_functionrD   r   is_coroutineis_decoratedrL   rN   r    r!   rO   rF   r   r]   r   r(   rG   rH   rY   implementation_artifact)r>   private_apienclosing_funcrS   rT   _r1   r1   r2   decode_enclosing_agen_types   s4   


rk   c                 C   s   t | jdkrt| jj| jj}n| jr%t | jd dkr%| jd d }n| jS tt| j	}t
| \}}|durQ|durQ|j||| jtjddd | j	d|gS | jS )zbProvide a more specific argument and return type for yield_()
    inside an @async_generator.
    r   r@   Nzyield_ argumentzdeclared YieldTypesubtype	supertyperN   msgsubtype_labelsupertype_labelztyping.Awaitable)rG   	arg_typesr   rN   rB   rC   r^   r   r%   rK   rk   check_subtyper   INCOMPATIBLE_TYPESnamed_generic_type)r>   arg_typerh   rS   rT   r1   r1   r2   r-      s$   r-   c                 C   s  | j rt| j d dkrt| j d d }n| jS tt| j}t| \}}|du s-|du r0| jS t|t	rh|j
jdv rht|jdkrh|jdd \}}|j||| jtjddd |j||| jtjd	d
d | jS t|t	r|j|| jd|g| jtjddd | jS )z-Provide a better typecheck for yield_from_().r   r@   N)rZ   ztrio_typing.AsyncGeneratorztyping.AsyncGeneratorr\   zyield_from_ argument YieldTypezlocal declared YieldTyperl   zlocal declared SendTypezyield_from_ argument SendTypeztyping.AsyncIterablezyield_from_ argument typezexpected iterable type)rr   rG   r"   r^   r   r%   rK   rk   rD   r   rF   r(   rH   rs   rN   r   rt   ru   )r>   rv   rh   our_yield_typeour_send_typetheir_yield_typetheir_send_typer1   r1   r2   r.      sV   
r.   Tr9   c                 C   s  z| j rt| j d dkrtdt| j d d }t|tr(tt| jts,tdd}d}d}d}tt|j	|j D ]v\}\}}	t|	}	t|	t
rY|tkrY|dksVJ |}q=t|	ttfr|tkrt|	trt|	jD ]}
t|
tr|
jstdd |
j	D r|
}	 nqnq=tt|	j	|	j D ]!\}\}}t|}t|t
r|tkr|dkrtd|}|}|	}qq=|dkrtd	|dks|du rtd
g }g }tddD ]}t|j }|j|j d| ttt | |j |d d  |j	d| tgt|  |j	|d d  |jd| dgt|  |j|d d  d||< ||j|d| ttt | ||d d  |j	d| tgt|  |j	|d d  |jd| dgt|  |j|d d  t|jttt | d |r|td|d|t|j | d g | jdg | j j!| j j"t
t#j$d q|td|d|t|j | d g | jdg | j j!| j j"d qt%|W S  ty } z| j&d|| j  | jW  Y d}~S d}~ww )a  Automate the boilerplate for writing functions that accept
    arbitrary positional arguments of the same type accepted by
    a callable.

    For example, this supports writing::

        @trio_typing.takes_callable_and_args
        def start_soon(
            self,
            async_fn: Callable[[VarArg()], Any],
            *args: Any,
        ) -> None: ...

    instead of::

        T1 = TypeVar("T1")
        T2 = TypeVar("T2")
        T3 = TypeVar("T3")
        T4 = TypeVar("T4")

        @overload
        def start_soon(
            self,
            async_fn: Callable[[], Any],
        ) -> None: ...

        @overload
        def start_soon(
            self,
            async_fn: Callable[[T1], Any],
            __arg1: T1,
        ) -> None: ...

        @overload
        def start_soon(
            self,
            async_fn: Callable[[T1, T2], Any],
            __arg1: T1,
            __arg2: T2
        ) -> None: ...

        # etc

    r   r@   zmust be used as a decoratorNc                 s   s    | ]}|t kV  qd S )N)r   ).0kind_r1   r1   r2   	<genexpr>  s    z3takes_callable_and_args_callback.<locals>.<genexpr>zSdecorated function may only take one callable that has an argument of type VarArg()z'decorated function must take *args: Anyz\decorated function must take a callable that has a argument of type mypy_extensions.VarArg()   )rr   	arg_kinds	arg_names)rr   r   r   	variablesz__T{}zbuiltins.object)rB   rC   default)rB   rC   z+invalid use of @takes_callable_and_args: {})'rr   rG   rI   r"   rD   r   r^   	enumeratezipr   r    r   r   r   r#   rE   is_ellipsis_argsanyranger`   r_   r   r   r
   r   rJ   r   r   r   rM   rK   ru   rN   rB   rC   r!   from_omitted_genericsr   rL   )r>   r9   fn_typecallable_idxcallable_args_idxcallable_tyargs_idxidxkindtyrW   idx_r}   ty_expanded_fnstype_var_typesarg_idxrr   rX   r1   r1   r2   r+   5  s   /





r+   versionc                 C   s0   t | }|t dk rtd|t dk rtS tS )Nz1.0z7This version of trio-typing requires at least mypy 1.0.z1.4)parse_versionRuntimeErrorr8   r'   )r   mypy_versionr1   r1   r2   plugin  s   r   )T)=sys	functoolsr   typingr   r   r   r   r   r   typing_extensionsr	   r
   typing_Typemypyr   mypy.pluginr   r   r   r   
mypy.nodesr   r   r   r   r   r   r   r   
mypy.typesr   r   r   r   r   r   r   r   r    r!   r"   r#   mypy.typeopsr$   mypy.checkerr%   packaging.versionr&   r   r'   r8   rY   r,   rk   r-   r.   boolr+   r7   r   r1   r1   r1   r2   <module>   sF     (<


V%*7
 =