
    i.                        % S SK r S SKrS SKrS SKJr  S SKJrJr  S SKJ	r	  SSK
JrJr  SSKJrJr  SSKJrJrJr  SS	KJr  S
/r\R.                  S:X  a,  \	" 5       r\	\S'   SrS\ R6                  S\ R6                  4S jrOS\ R6                  S\ R6                  4S jrS rSrSrSr Sr!Sr"Sr#Sr$Sr%Sr&Sr'S r(Sr)Sr* \RV                  " 5       S\,S\S\,4S j5       r-\RV                  " 5       S\,S\,S\S\S\,4
S j5       r. " S S
5      r/g)    N)suppress)AnyOptional)WeakKeyDictionary   )ffilib)	CurlECodeCurlMOpt)DEFAULT_CACERTCurl	CurlError)CurlCffiWarning	AsyncCurlwin32
_selectorsa  
    Proactor event loop does not implement add_reader family of methods required.
    Registering an additional selector thread for add_reader support.
    To avoid this warning use:
        asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
    asyncio_loopreturnc           
      (  ^ ^^ T [         ;   a	  [         T    $ [        T [        [        S[	        S5      5      5      (       d  T $ [
        R                  " [        [        SS9  SSK	J
n  U" T 5      =m[         T '   T R                  mU UU4S jnUT l        T$ )zGet selector-compatible loop

Returns an object with ``add_reader`` family of methods,
either the loop itself or a SelectorThread instance.

Workaround Windows proactor removal of *reader methods.
ProactorEventLoopN   
stacklevelr   )AddThreadSelectorEventLoopc                  `   > TT l         [        R                  T S 5        TR                  5         g N)closer   pop)r   
loop_closeselector_loops   :/app/mltbenv/lib/python3.13/site-packages/curl_cffi/aio.py_close_selector_and_loop.get_selector.<locals>._close_selector_and_loop7   s'     ",LNN<.!    )r   
isinstancegetattrasynciotypewarningswarnPROACTOR_WARNINGr   _asyncio_selectorr   r   )r   r   r"   r   r    s   `  @@r!   get_selectorr-      s     :%l++''+>T
K
 
  &AFA3M4
 	

<0
 "''
	" 6r$   loopc                     U $ r    )r.   s    r!   r-   r-   C   s    r$   r         
timeout_msclientpc                    [         R                  " U5      nUR                  (       a!  UR                  R                  5         SUl        UR                  R                  US-  UR                  [        [        5      Ul        g)z<
see: https://curl.se/libcurl/c/CURLMOPT_TIMERFUNCTION.html
Ni  r   )	r   from_handle_timercancelr.   
call_laterprocess_dataCURL_SOCKET_TIMEOUTCURL_POLL_NONE)curlmr4   r5   
async_curls       r!   timer_functionr@   u   sl    
 )J   " 
 #22T	J r$   sockfdwhatdatac                    [         R                  " U5      nUR                  nXR                  ;   a"  UR	                  U5        UR                  U5        U[        -  (       a<  UR                  XR                  U[        5        UR                  R                  U5        U[        -  (       a<  UR                  XR                  U[        5        UR                  R                  U5        U[        :X  a  UR                  R                  U5        g)zWThis callback is called when libcurl decides it's time to interact with certain
socketsr   )r   r7   r.   _sockfdsremove_readerremove_writerCURL_POLL_IN
add_readerr;   CURL_CSELECT_INaddCURL_POLL_OUT
add_writerCURL_CSELECT_OUTCURL_POLL_REMOVEremove)curlrA   rB   r5   rC   r?   r.   s          r!   socket_functionrR      s    
 )J??D $$$6"6" l 7 7Q' m 7 7AQR' ""6*r$   c                       \ rS rSrSrSS\4S jjrS rS rS r	S	\
4S
 jrS\S\S\4S jrS\S\4S jrS	\
4S jrS	\
4S jrS	\
4S jrS	\
4S jrS\S\4S jrS rSrg)r      zdWrapper around curl_multi handle to provide asyncio support. It uses the libcurl
socket_action APIs.Ncacertc                 t   [         R                  " 5       U l        U=(       d    [        U l        0 U l        0 U l        [        5       U l        [        Ub  UO[        R                  " 5       5      U l        U R                  R                  U R                  5       5      U l        SU l        U R#                  5         g)zw
Parameters:
    cacert: CA cert path to use, by default, certs from ``certifi`` are used.
    loop: EventLoop to use.
N)r	   curl_multi_init_curlmr   _cacert_curl2future
_curl2curlsetrE   r-   r'   get_running_loopr.   create_task_force_timeout_timeout_checkerr8   _setup)selfrU   r.   s      r!   __init__AsyncCurl.__init__   s     ))+/8:13"%% $D'*B*B*D
	 !%		 5 5d6I6I6K L59r$   c                    U R                  [        R                  [        R                  5        U R                  [        R
                  [        R                  5        [        R                  " U 5      U l	        U R                  [        R                  U R                  5        U R                  [        R                  U R                  5        g r   )setoptr   TIMERFUNCTIONr	   r@   SOCKETFUNCTIONrR   r   
new_handle_self_handle
SOCKETDATA	TIMERDATArb   s    r!   ra   AsyncCurl._setup   s{    H**C,>,>?H++S-@-@ANN40H''):):;H&&(9(9:r$   c                 (  #    U R                   R                  5         [        [        R                  5         U R                   I Sh  vN   SSS5        U R
                  R                  5        Ho  u  p[        R                  " U R                  UR                  5        UR                  5       (       a  MG  UR                  5       (       a  M^  UR                  S5        Mq     [        R                  " U R                  5        SU l	        U R                   H9  nU R                   R#                  U5        U R                   R%                  U5        M;     U R&                  (       a  U R&                  R                  5         gg GN7! , (       d  f       GN<= f7f)z?Close and cleanup running timers, readers, writers and handles.N)r`   r9   r   r'   CancelledErrorrZ   itemsr	   curl_multi_remove_handlerX   _curldone	cancelled
set_resultcurl_multi_cleanuprE   r.   rF   rG   r8   )rb   rQ   futurerA   s       r!   r   AsyncCurl.close   s     	$$&g,,-'''' . !--335LD((djjA;;==)9)9););!!$' 6 	t{{+ mmFII##F+II##F+ $
 ;;KK  % ( .-s<   4FF E=F A%F4FB2F=F  
F
Fc                    #     U R                   (       d  gU R                  [        [        5        [        R
                  " S5      I Sh  vN   ML   N7f)zhThis coroutine is used to safeguard from any missing signals from curl, and
put everything back on trackg?N)rX   socket_actionr<   r=   r'   sleeprm   s    r!   r_   AsyncCurl._force_timeout   sA      ;;2NC--$$$	  %s   AA	A
ArQ   c                    UR                  5         [        R                  " U R                  UR                  5      nU R                  U5        U R                  R                  5       nX0R                  U'   XR                  UR                  '   U$ )zfAdd a curl handle to be managed by curl_multi. This is the equivalent of
`perform` in the async world.)
_ensure_cacertr	   curl_multi_add_handlerX   rs   _check_errorr.   create_futurerZ   r[   )rb   rQ   errcoderx   s       r!   
add_handleAsyncCurl.add_handle   sm     	++DKKD'"((*"($&*

#r$   rA   
ev_bitmaskr   c                     [         R                  " S5      n[        R                  " U R                  XU5      nU R                  U5        US   $ )zQwrapper for curl_multi_socket_action,
returns the number of running curl handles.int *r   )r   newr	   curl_multi_socket_actionrX   r   )rb   rA   r   running_handler   s        r!   r{   AsyncCurl.socket_action   sH     )..KK^
 	'"a  r$   c                    U R                   (       d  [        R                  " S[        SS9  gU R	                  X5        [
        R                  " S5      n  [        R                  " U R                   U5      nU[
        R                  :X  a  gUR                  [        :X  ai  U R                  UR                     nUR                  R                  nUS:X  a  U R!                  U5        O.U R#                  XUR%                  US5      5        O['        S5         M  ! [(         a    [        R                  " S	[        SS9   N(f = f)
z8Call curl_multi_info_read to read data for given socket.z0Curlm already closed! quitting from process_datar   r   Nr   r   performzNOT DONEzLUnexpected curl multi state in process_data, please open an issue on GitHub
)rX   r)   r*   r   r{   r   r   r	   curl_multi_info_readNULLmsgCURLMSG_DONEr[   easy_handlerC   resultrv   set_exception
_get_errorprint	Exception)rb   rA   r   msg_in_queuecurl_msgrQ   retcodes          r!   r;   AsyncCurl.process_data  s    {{MMB
 6.www'33DKKNsxx'<<</??8+?+?@D&mm22G!|-**4)1TU*%   7# 	s%   5D AD '!D 	D $D>=D>c                     [         R                  " U R                  UR                  5      nU R	                  U5        U R
                  R                  UR                  S 5        U R                  R                  US 5      $ r   )r	   rr   rX   rs   r   r[   r   rZ   )rb   rQ   r   s      r!   _pop_futureAsyncCurl._pop_future'  s[    ..t{{DJJG'"DJJ-  $$T400r$   c                     U R                  U5      nU(       a=  UR                  5       (       d'  UR                  5       (       d  UR                  5         gggg)z&Cancel a future for given curl handle.N)r   rt   ru   r9   rb   rQ   rx   s      r!   remove_handleAsyncCurl.remove_handle-  s@    !!$'&++--0@0@0B0BMMO 1C-6r$   c                     U R                  U5      nU(       a>  UR                  5       (       d(  UR                  5       (       d  UR                  S5        gggg)z,Mark a future as done for given curl handle.N)r   rt   ru   rv   r   s      r!   rv   AsyncCurl.set_result3  sE    !!$'&++--0@0@0B0Bd# 1C-6r$   c                     U R                  U5      nU(       a>  UR                  5       (       d(  UR                  5       (       d  UR                  U5        gggg)z2Raise exception of a future for given curl handle.N)r   rt   ru   r   )rb   rQ   	exceptionrx   s       r!   r   AsyncCurl.set_exception9  sE    !!$'&++--0@0@0B0B  + 1C-6r$   r   argsc           	          U[         R                  :X  a  g [        R                  " U5      nSR	                  U Vs/ s H  n[        U5      PM     sn5      n[        SU SU SU S35      es  snf )N z
Failed in z
, multi: (z) z. See https://curl.se/libcurl/c/libcurl-errors.html first for more details. Please open an issue on GitHub to help debug this error.)r
   OKr	   curl_multi_strerrorjoinstrr   )rb   r   r   errmsgaactions         r!   r   AsyncCurl._check_error?  ss    ill"((1404a3q6401
7)2fX >P P
 	
 1s   A,c                 8   U[         R                  [         R                  [         R                  [         R                  [         R
                  [         R                  4;   a  [        R                  " SU5      nOUn[        R                  " U R                  X5      $ )z!Wrapper around curl_multi_setopt.zlong*)r   
PIPELININGMAXCONNECTSMAX_HOST_CONNECTIONSMAX_PIPELINE_LENGTHMAX_TOTAL_CONNECTIONSMAX_CONCURRENT_STREAMSr   r   r	   curl_multi_setoptrX   )rb   optionvaluec_values       r!   rf   AsyncCurl.setoptJ  ss      ))((**++
 
 gggu-GG$$T[[&BBr$   )	rY   r[   rZ   rX   rj   rE   r`   r8   r.   ) N)__name__
__module____qualname____firstlineno____doc__r   rc   ra   r   r_   r   r   intr{   r;   r   r   rv   r   r   r   rf   __static_attributes__r0   r$   r!   r   r      s    s $;!6%
t 
!C !S !S !"3 "C "H1 1$ $t $,$ ,	
C 	
 	
Cr$   )0r'   sysr)   
contextlibr   typingr   r   weakrefr   _wrapperr   r	   constr
   r   rQ   r   r   r   utilsr   __all__platformr   __annotations__r+   AbstractEventLoopr-   r=   rH   rL   CURL_POLL_INOUTrO   r<   CURL_SOCKET_BADrJ   rN   CURL_CSELECT_ERRr   CURLPIPE_NOTHINGCURLPIPE_HTTP1CURLPIPE_MULTIPLEX
def_externr   r@   rR   r   r0   r$   r!   <module>r      s_    
     %  & 1 1 "-<<7$5$7J!7&//&		"	"&T744 9R9R        4 c C C  . # S 3 c c  :lC lCr$   