
    iw1                       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 dd
lmZ ddlmZ ej6                  Zej:                  Zej>                  Z ejB                  Z"ej6                  Z#ej:                  Z$ej>                  Z% ejL                  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      reej^                  ej`                  z  ejb                  z  eej^                  ejd                  z  ejb                  z  e ej^                  ej`                  ejd                  z  ejb                  z  z  iZ3ni Z3dddZ4 e.ed      r4eejj                  eejl                  e ejj                  ejl                  z  iZ7ni Z7dddZ8d dZ9erejt                  Z:de;d<   dejx                  v r?ejx                  d   Z=e=j}                  d      r	e= e?       vr e@de=       e?       e=   ZAyerej                  dk7  r
 e9       se:ZAyej                   eCedd      u re-ZAy e.ed      re8ZAye)ZAy)!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)EventTimeoutErrorget_event_loopwait_for)DefaultSelector   )errors)RVPQGen	PQGenConnWaitFunc)Ready)Wait)_psycopgc                   	 t        |       }t               5 }|j                  ||       	 |j                  |      x}s| j	                  t
               +|j                  |       |d   d   }| j	                  |      }|j                  ||       g# 1 sw Y   yxY w# t        $ r}|j                  }|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`.
    timeoutr   r	   N	nextr   registerselectsend
READY_NONE
unregisterStopIterationvalue)	genfilenointervalsselrlistreadyexrvs	            o/var/www/html/hwPaymentPortal-be-dev/hw-payment-portal-api/venv/lib/python3.12/site-packages/psycopg/waiting.pywait_selectorr(   &   s    I 
	(#LL#!$H!===HHZ(v&aHHUOVQ' 
	( 
	(  	s5   B A;BBB B 	B?'B:4B?:B?c                   	 t        |       \  }}|sd}t               5 }|j                  ||       	 |j                  |      x}s| j	                  t
               +|j                  |       |d   d   }| j	                  |      \  }}|j                  ||       j# 1 sw Y   yxY w# t        $ r}|j                  }|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.
    Nr   r   r	   r   )	r   r    r   r!   r"   r#   r$   r%   r&   s	            r'   	wait_connr*   G   s    I	H 
	(#LL#!$H!===HHZ(v&aHHUO	VQ' 
	( 
	(  	s5   B( A>BB%!B( %B( (	C	1C>C	C	c                L  
K   t               
t               }d
fd}	 t        |       }	 |t        z  }|t        z  }|s|st        j                  d|       
j                          d|r|j                  ||t               |r|j                  ||t               	 |$	 t        
j                         |       d{    n
j                          d{    |r|j                  |       |r|j!                  |       	 | j#                        }7 V# t        $ r Y Fw xY w7 N# |r|j                  |       |r|j!                  |       w w xY w# t$        $ r#}t        j&                  t)        |            d}~wt*        $ r}|j,                  }	|	cY d}~S d}~ww xY w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.
    c                0    | z  j                          y Nsetstateevr$   s    r'   wakeupzwait_async.<locals>.wakeup}   s    
    bad poll status: r   Nr1   r   returnNone)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    loopr3   r!   readerwriterr%   r&   r2   r$   s             @@r'   
wait_asyncrK   i   sz     
BD
!IZFZFfoo(9!&=>>HHJE88/'&rwwy(;;; '')OO&&v.&&v.A1  <'  $&&v.&&v.   *  R)) 	s   F$A>E  D* #D  DD D* D(D* 9E D 	D%"D* $D%%D* *)EE 	F!E==F!	FF!F$F!!F$c                  
K   t               
t               }d
fd}	 t        |       \  }}	 |t        z  }|t        z  }|s|st        j                  d|       
j                          d|r|j                  ||t               |r|j                  ||t               	 |r$	 t        
j                         |       d{    n
j                          d{    |r|j                  |       |r|j!                  |       	 | j#                        \  }}7 Y# t        $ r Y Iw xY w7 Q# |r|j                  |       |r|j!                  |       w w xY w# t$        $ r}|j&                  }	|	cY d}~S d}~ww xY w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.
    c                *    | j                          y r-   r.   r0   s    r'   r3   zwait_conn_async.<locals>.wakeup   s    
r4   r5   r   Nr6   )r   r   r   r9   r:   r;   r<   r=   r>   r?   r@   rA   r   rB   r   rC   rD   r   r   r   )r   r    rH   r3   r   r!   rI   rJ   r%   r&   r2   r$   s             @@r'   wait_conn_asyncrN      sa     
BD
I	ZFZFfoo(9!&=>>HHJE88/&rwwy(;;; '')OO&&v.&&v.IFA1  <'  $&&v.&&v.   	s   F BE #D0 &D DD D0 D.D0 !<E D 	D+(D0 *D++D0 0)EE 	E=%E82E=3F 8E==F c                P   	 t        |       }d}|f}	 t        j                  |t        z  r|n||t        z  r|n|||      \  }}}d}	|rt        }	|r	|	t
        z  }	|	s| j                  t               `| j                  |	      }q# t        $ r}
|
j                  }|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.
     r   N)
r   r   r9   r:   r?   rA   r   r   r   r   )r   r   r    r!   emptyfnlistrlwlxlr$   r%   r&   s               r'   wait_selectrV      s    If*%f*%	JBB E $A! $  	s   BB 	B%B B% B%EpollSelectorc                   	 t        |       }||dk  rd}t        j                         5 }t        |   }|j	                  ||       	 |j                  |      x}s| j                  t               *|d   d   }d}|t        j                   z  rt        }|t        j                   z  r	|t        z  }| j                  |      }t        |   }|j                  ||       # 1 sw Y   yxY w# t        $ r}	|	j                  }
|
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        r	   )r   r   epoll_epoll_evmasksr   pollr   r   EPOLLOUTr?   EPOLLINrA   modifyr   r   )r   r   r    r!   rY   evmaskfileevsr2   r$   r%   r&   s              r'   
wait_epollra     s    Ix!|H\\^ 	-u#A&FNN66*#(::h#777HHZ(QZ]((#E'W$EHHUO'*VV, 	- 	-"  	s5   (C* B4CC'#C* 'C* *	D3D DDPollSelectorc                    	 t        |       }||dk  rd}nt        |dz        }t        j                         }t        |   }|j                  ||       	 |j                  |      x}s| j                  t               *|d   d   }d}|t        j                   z  rt        }|t        j                   z  r	|t        z  }| j                  |      }t        |   }|j                  ||       # t        $ r}	|	j                  }
|
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     @@r	   )r   intr   r[   _poll_evmasksr   r   r   POLLOUTr?   POLLINrA   r^   r   r   )r   r   r    r!   r[   r_   r`   r2   r$   r%   r&   s              r'   	wait_pollrh   F  s    Ix!|H8f,-H{{}q!ff%#yy22G2$ABEV^^O#V]]N" A"1%FKK'   	s   C*C, ,	D5DDDc                     t         j                  j                  d      x} r	 | j                  d      ry	 yy# t        $ r }t
        j                  d|       Y d}~yd}~ww xY w)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_patchedrr   k  sf     KKOOO,,q,	N""8, -
   	NNNH"MM	Ns   8 	A!AA!r   rB   PSYCOPG_WAIT_FUNCwait_zHPSYCOPG_WAIT_FUNC should be the name of an available wait function; got win32SelectSelectorr-   )r   z	PQGen[RV]r   rd   r    float | Noner7   r   )r   zPQGenConn[RV]r    rw   r7   r   )r7   bool)D__doc__
__future__r   osrj   r   logging	selectorsasyncior   r   r   r   r    r
   r;   abcr   r   r   r   _enumsr   r   _cmoduler   Rr9   Wr:   RWWAIT_RWNONEr   r?   rA   READY_RW	getLogger__name__ro   r(   r*   rK   rN   rV   hasattrEPOLLONESHOTr]   EPOLLERRr\   rZ   ra   rg   rf   re   rh   rr   wait_c__annotations__environfname
startswithglobalsImportErrorrB   platformgetattrrP   r4   r'   <module>r      s7   # 	 
    A A %  / / "   		
''ZZ

''
''88			8	$BD:z7zD 9o&##fnn4vF##foo5G$$>>FOO+foo=?N N)X 9n%/M M"J( __F  "**$JJ*+EG$WY(>9
 	
 9UD
 #,,')2D2FD')5Et"LLDY' D Dr4   