
    pj\2                       U d 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Zddlm	Z	m
Z
mZ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 dd
lmZ ej        Zej        Zej        Z ej!        Z"ej        Z#ej        Z$ej        Z% ej&        e'          Z(d&d'dZ)d&d(dZ*d&d'dZ+d&d(dZ,d&d'dZ- e.ed          rPeej/        ej0        z  ej1        z  eej/        ej2        z  ej1        z  e ej/        ej0        ej2        z  ej1        z  z  iZ3ni Z3d&d'dZ4 e.ed          r eej5        eej6        e ej5        ej6        z  iZ7ni Z7d&d'dZ8d)dZ9erej:        Z:de;d <   d!ej<        v rNej<        d!         Z=e=>                    d"          re= e?            vr e@d#e=           e?            e=         ZAdS erejB        d$k    r e9            se:ZAdS ej         eCed%d          u re-ZAdS  e.ed          re8ZAdS e)ZAdS )*z
Code concerned with waiting in different contexts (blocking, async, etc).

These functions are designed to consume the generators returned by the
`generators` module function and to return their final value.

    )annotationsN)get_event_loopwait_forEventTimeoutError)DefaultSelector   )errors)RVPQGen	PQGenConnWaitFunc)WaitReady)_psycopggen	PQGen[RV]filenointintervalfloat | Nonereturnr   c                   	 t          |           }t                      5 }|                    ||           	 |                    |          }|s|                     t
                     4|                    |           |d         d         }|                     |          }|                    ||           # 1 swxY w Y   dS # t          $ r"}|j        r|j        d         nd}|cY d}~S d}~ww xY w)a8  
    Wait for a generator using the best strategy available.

    :param gen: a generator performing database operations and yielding
        `Ready` values when it would block.
    :param fileno: the file descriptor to wait on.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If zero or None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Consume `!gen`, scheduling `fileno` for completion when it is reported to
    block. Once ready again send the ready state back to `!gen`.
    Ttimeoutr   r	   N	nextr   registerselectsend
READY_NONE
unregisterStopIterationargs)	r   r   r   sselrlistreadyexrvs	            _/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/psycopg/waiting.pywait_selectorr,   %   s-   II 	(#LL###	(

8
44 HHZ(((v&&&aHHUOOVQ'''	(	( 	( 	( 	( 	( 	( 	( 	( 	( 	(    !w0D						s;   C BB99B==C  B=C 
C2C-'C2-C2PQGenConn[RV]c                   	 t          |           \  }}|sd}t                      5 }|                    ||           	 |                    |          }|s|                     t
                     4|                    |           |d         d         }|                     |          \  }}|                    ||           # 1 swxY w Y   dS # t          $ r"}|j        r|j        d         nd}|cY d}~S d}~ww xY w)a  
    Wait for a connection generator using the best strategy available.

    :param gen: a generator performing database operations and yielding
        (fd, `Ready`) pairs when it would block.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If zero or None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but take the fileno to wait from the generator
    itself, which might change during processing.
    NTr   r   r	   r   )	r   r   r   r%   r&   r'   r(   r)   r*   s	            r+   	wait_connr/   G   sB   II	 	H 	(#LL###	(

8
44 HHZ(((v&&&aHHUOO	VQ'''	(	( 	( 	( 	( 	( 	( 	( 	( 	( 	(    !w0D						s;   $C BCCC 
CC 
C<C71C<7C<c                  
K   t                      
t                      }d

fd}	 t          |           }	 |t          z  }|t          z  }|s|st          j        d|           
                                 d|r|                    ||t                     |r|
                    ||t                     	 |:	 t          
                                |           d	{V  n*# t          $ r Y nw xY w
                                 d	{V  |r|                    |           |r|                    |           n4# |r|                    |           |r|                    |           w w xY w|                               }R# t$          $ r&}t          j        t)          |                    d	}~wt*          $ r"}|j        r|j        d         nd	}	|	cY d	}~S d	}~ww xY w)a  
    Coroutine waiting for a generator to complete.

    :param gen: a generator performing database operations and yielding
        `Ready` values when it would block.
    :param fileno: the file descriptor to wait on.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but exposing an `asyncio` interface.
    stater   r   Nonec                :    | z                                    d S Nsetr1   evr(   s    r+   wakeupzwait_async.<locals>.wakeup~   s    
    Tbad poll status: r   Nr1   r   r   r2   )r   r   r   WAIT_RWAIT_WeInternalErrorclear
add_readerREADY_R
add_writerREADY_Wr   waitr   remove_readerremove_writerr    OSErrorOperationalErrorstrr#   r$   )r   r   r   loopr9   r%   readerwriterr)   r*   r8   r(   s             @@r+   
wait_asyncrO   j   s\      
BD      
!II	 ZFZF ?& ?o&=!&=&=>>>HHJJJE 9888 9888/'&rwwyy(;;;;;;;;;;'    ''))OOOOOOO /&&v... /&&v...  /&&v... /&&v..../A1	 4  * * * R)))   !w0D						sf   BF ;E  >(C' &E  '
C41E  3C44E  /F  1E11F 
G%!F66G%G G% G%c                  
K   t                      
t                      }d

fd}	 t          |           \  }}	 |t          z  }|t          z  }|s|st          j        d|           
                                 d|r|                    ||t                     |r|
                    ||t                     	 |r:	 t          
                                |           d	{V  n*# t          $ r Y nw xY w
                                 d	{V  |r|                    |           |r|                    |           n4# |r|                    |           |r|                    |           w w xY w|                               \  }}U# t$          $ r"}|j        r|j        d         nd	}	|	cY d	}~S d	}~ww xY w)a  
    Coroutine waiting for a connection generator to complete.

    :param gen: a generator performing database operations and yielding
        (fd, `Ready`) pairs when it would block.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If zero or None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but take the fileno to wait from the generator
    itself, which might change during processing.
    r1   r   r   r2   c                4    |                                   d S r4   r5   r7   s    r+   r9   zwait_conn_async.<locals>.wakeup   s    
r:   Tr;   r   Nr<   )r   r   r   r=   r>   r?   r@   rA   rB   rC   rD   rE   r   rF   r   rG   rH   r    r#   r$   )r   r   rL   r9   r   r%   rM   rN   r)   r*   r8   r(   s             @@r+   wait_conn_asyncrR      s9      
BD      
II		(ZFZF ?& ?o&=!&=&=>>>HHJJJE 9888 9888/ $&rwwyy(;;;;;;;;;;'    ''))OOOOOOO /&&v... /&&v...  /&&v... /&&v..../IFA1	(4    !w0D						sZ   BF >E (C* )E *
C74E 6C77E /F 1E44F 
F=F82F=8F=c                   	 t          |           }d}|f}	 t          j        |t          z  r|n||t          z  r|n|||          \  }}}d}	|rt          }	|r
|	t
          z  }	|	s|                     t                     h|                     |	          }}# t          $ r"}
|
j	        r|
j	        d         nd}|cY d}
~
S d}
~
ww xY w)z
    Wait for a generator using select where supported.

    BUG: on Linux, can't select on FD >= 1024. On Windows it's fine.
     Tr   N)
r   r   r=   r>   rC   rE   r    r!   r#   r$   )r   r   r   r%   emptyfnlistrlwlxlr(   r)   r*   s               r+   wait_selectrZ      s    II	 f*/%f*/%	 JBB E   !  $$$A!	 $    !w0D						s   BB 
C B;5C ;C EpollSelectorc                v   	 t          |           }||dk     rd}t          j                    5 }t          |         }|                    ||           	 |                    |          }|s|                     t                     3|d         d         }d}|t          j         z  rt          }|t          j
         z  r
|t          z  }|                     |          }t          |         }|                    ||           # 1 swxY w Y   dS # t          $ r"}	|	j        r|	j        d         nd}
|
cY d}	~	S d}	~	ww xY w)a$  
    Wait for a generator using epoll where supported.

    Parameters are like for `wait()`. If it is detected that the best selector
    strategy is `epoll` then this function will be used instead of `wait`.

    See also: https://linux.die.net/man/2/epoll_ctl

    BUG: if the connection FD is closed, `epoll.poll()` hangs. Same for
    EpollSelector. For this reason, wait_poll() is currently preferable.
    To reproduce the bug:

        export PSYCOPG_WAIT_FUNC=wait_epoll
        pytest tests/test_concurrency.py::test_concurrent_close
    Nr   g        Tr	   )r   r   epoll_epoll_evmasksr   pollr    r!   EPOLLOUTrC   EPOLLINrE   modifyr#   r$   )r   r   r   r%   r]   evmaskfileevsr8   r(   r)   r*   s              r+   
wait_epollre     sw    IIx!||H\^^ 	-u#A&FNN66***-**X.. HHZ(((QZ](( $#E' %W$EHHUOO'*VV,,,-	- 	- 	- 	- 	- 	- 	- 	- 	- 	-$    !w0D						s;   ,D CC??DD DD 
D8D3-D83D8PollSelectorc                   	 t          |           }||dk     rd}nt          |dz            }t          j                    }t          |         }|                    ||           	 |                    |          }|s|                     t                     3|d         d         }d}|t          j         z  rt          }|t          j
         z  r
|t          z  }|                     |          }t          |         }|                    ||           # t          $ r"}	|	j        r|	j        d         nd}
|
cY d}	~	S d}	~	ww xY w)za
    Wait for a generator using poll where supported.

    Parameters are like for `wait()`.
    Nr   g     @@Tr	   )r   r   r   r_   _poll_evmasksr   r    r!   POLLOUTrC   POLLINrE   rb   r#   r$   )r   r   r   r%   r_   rc   rd   r8   r(   r)   r*   s              r+   	wait_pollrk   H  sP   IIx!||HH8f,--H{}}q!ff%%%	(ii))G $$$ABEV^O#  V]N" ! A"1%FKK'''	(     !w0D						s   DD 
D=D82D=8D=boolc                     t           j                            d          } | rK	 |                     d          rdS n2# t          $ r%}t
                              d|           Y d}~nd}~ww xY wdS )z
    Detect if some greenlet library has patched the select library.

    If this is the case, avoid to use the wait_c function as it doesn't behave
    in a collaborative way.

    Currently supported: gevent.
    zgevent.monkeyr   Tz+failed to detect gevent monkey-patching: %sNF)sysmodulesgetis_module_patched	Exceptionloggerwarning)mr)   s     r+   _is_select_patchedrv   n  s     	((A N	N""8,, t 	N 	N 	NNNH"MMMMMMMM	N 5s   ; 
A*A%%A*r   rF   PSYCOPG_WAIT_FUNCwait_zHPSYCOPG_WAIT_FUNC should be the name of an available wait function; got win32SelectSelectorr4   )r   r   r   r   r   r   r   r   )r   r-   r   r   r   r   )r   rl   )D__doc__
__future__r   osrn   r   logging	selectorsasyncior   r   r   r   r    r
   r?   abcr   r   r   r   _enumsr   r   _cmoduler   Rr=   Wr>   RWWAIT_RWNONEr!   rC   rE   READY_RW	getLogger__name__rs   r,   r/   rO   rR   rZ   hasattrEPOLLONESHOTra   EPOLLERRr`   r^   re   rj   ri   rh   rk   rv   wait_c__annotations__environfname
startswithglobalsImportErrorrF   platformgetattrrT   r:   r+   <module>r      s     # " " " " " 				 



       A A A A A A A A A A A A % % % % % %       / / / / / / / / / / / / 0 0 0 0 0 0 0 0      		
'Z

'
'8		8	$	$    D         F: : : : :z7 7 7 7 7z    D 79o&& #fn4vF#fo5G$>FO+fo=?NN N* * * * *Z 79n%% /MM M# # # # #L   *  _F  "*$$J*+EG$$ 
WWYY(>(>k 
 
 	
 799UDDD
  #,'))2D2D2F2F)DDD'')5Et"L"LLLDDDWY''  DDD DDDr:   