U :eۿ@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddl mZddl mZddl mZddl mZdd l mZdd l mZdd l mZdd l mZdd l mZddlmZdZe jdkredddZGdddejZGdddej Z!Gdddej"ej#Z$Gdddej%Z&GdddZ'ddZ(Gd d!d!e'Z)Gd"d#d#e)Z*Gd$d%d%e)Z+Gd&d'd'e'Z,Gd(d)d)e'Z-Gd*d+d+ej.Z/eZ0e/Z1dS),z2Selector event loop for Unix with signal handling.N) base_events)base_subprocess) constants) coroutines)events) exceptions)futures)selector_events)tasks) transports)logger)SelectorEventLoopAbstractChildWatcherSafeChildWatcherFastChildWatcherMultiLoopChildWatcherThreadedChildWatcherDefaultEventLoopPolicywin32z+Signals are not really supported on WindowscCsdS)zDummy signal handler.N)signumframerr8/usr/local/python38/lib/python3.8/asyncio/unix_events.py_sighandler_noop*srcseZdZdZd)fdd ZfddZddZd d Zd d Zd dZ ddZ d*ddZ d+ddZ d,ddZ ddZd-dddddddZd.dddddddd Zd!d"Zd#d$Zd%d&Zd'd(ZZS)/_UnixSelectorEventLoopzdUnix event loop. Adds signal handling and UNIX Domain Socket support to SelectorEventLoop. Ncst|i|_dSN)super__init___signal_handlers)selfselector __class__rrr5s z_UnixSelectorEventLoop.__init__csZtts.t|jD]}||qn(|jrVtjd|dt |d|j dS)NzClosing the loop z@ on interpreter shutdown stage, skipping signal handlers removalsource) rclosesys is_finalizinglistrremove_signal_handlerwarningswarnResourceWarningclearr sigr"rrr&9s z_UnixSelectorEventLoop.closecCs|D]}|sq||qdSr)_handle_signal)r datarrrr_process_self_dataGsz)_UnixSelectorEventLoop._process_self_datac GsLt|st|rtd|||zt|j Wn2t t fk rt}zt t |W5d}~XYnXt|||d}||j|<zt|tt|dWnt k rF}zz|j|=|jsztdWn4t t fk r}ztd|W5d}~XYnX|jtjkr4t d|dnW5d}~XYnXdS)zAdd a handler for a signal. UNIX only. Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler. z3coroutines cannot be used with add_signal_handler()NFset_wakeup_fd(-1) failed: %ssig  cannot be caught)rZ iscoroutineZiscoroutinefunction TypeError _check_signal _check_closedsignal set_wakeup_fdZ_csockfileno ValueErrorOSError RuntimeErrorstrrHandlerr siginterruptr infoerrnoEINVAL)r r0callbackargsexchandleZnexcrrradd_signal_handlerNs2    z)_UnixSelectorEventLoop.add_signal_handlercCs8|j|}|dkrdS|jr*||n ||dS)z2Internal helper that is the actual signal handler.N)rgetZ _cancelledr*Z_add_callback_signalsafe)r r0rJrrrr1{s   z%_UnixSelectorEventLoop._handle_signalc Cs||z |j|=Wntk r,YdSX|tjkr@tj}ntj}zt||WnBtk r}z$|jtj krt d|dnW5d}~XYnX|jszt dWn2t tfk r}zt d|W5d}~XYnXdS)zwRemove a handler for a signal. UNIX only. Return True if a signal handler was removed, False if not. Fr6r7Nr4r5T)r9rKeyErrorr;SIGINTdefault_int_handlerSIG_DFLr?rErFr@r<r>r rD)r r0handlerrIrrrr*s(    z,_UnixSelectorEventLoop.remove_signal_handlercCs6t|tstd||tkr2td|dS)zInternal helper to validate a signal. Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler. zsig must be an int, not zinvalid signal number N) isinstanceintr8r; valid_signalsr>r/rrrr9s  z$_UnixSelectorEventLoop._check_signalcCst|||||Sr)_UnixReadPipeTransportr pipeprotocolwaiterextrarrr_make_read_pipe_transportsz0_UnixSelectorEventLoop._make_read_pipe_transportcCst|||||Sr)_UnixWritePipeTransportrVrrr_make_write_pipe_transportsz1_UnixSelectorEventLoop._make_write_pipe_transportc st} | std|} t||||||||f| |d| } | | |j| z| IdHWnDt t fk rYn,t k r| | IdHYnXW5QRX| S)NzRasyncio.get_child_watcher() is not activated, subprocess support is not installed.)rYrZ)rget_child_watcher is_activer@ create_future_UnixSubprocessTransportadd_child_handlerZget_pid_child_watcher_callback SystemExitKeyboardInterrupt BaseExceptionr&_wait) r rXrHshellstdinstdoutstderrbufsizerZkwargswatcherrYtransprrr_make_subprocess_transports8   z1_UnixSelectorEventLoop._make_subprocess_transportcCs||j|dSr)call_soon_threadsafeZ_process_exited)r pid returncoderorrrrcsz._UnixSelectorEventLoop._child_watcher_callback)sslsockserver_hostnamessl_handshake_timeoutc s |dkst|tst|r,|dkrLtdn |dk rosfspathsocketAF_UNIX SOCK_STREAM setblockingZ sock_connectr&familytypeZ_create_connection_transport) r protocol_factorypathrtrurvrw transportrXrrrcreate_unix_connectionsT      z-_UnixSelectorEventLoop.create_unix_connectiondT)rubacklogrtrw start_servingc st|trtd|dk r&|s&td|dk rH|dk r@tdt|}ttjtj}|ddkrz t t |j rt |WnBt k rYn0tk r}ztd||W5d}~XYnXz||Wnltk r0} z8|| jtjkrd|d} ttj| dnW5d} ~ XYn|YnXn<|dkrZtd |jtjksv|jtjkrtd ||d t||g||||} |r| tjd|d IdH| S) Nz*ssl argument must be an SSLContext or Nonerxryr)rz2Unable to check or remove stale UNIX socket %r: %rzAddress z is already in usez-path was not specified, and no sock specifiedrzF)loop)rRboolr8r>r|r}r~rrstatS_ISSOCKst_moderemoveFileNotFoundErrorr?r errorbindr&rEZ EADDRINUSErrrrZServerZ_start_servingr sleep) r rrrurrtrwrerrrImsgZserverrrrcreate_unix_serversn           z)_UnixSelectorEventLoop.create_unix_serverc sz tjWn,tk r6}ztdW5d}~XYnXz |}Wn2ttjfk rv}ztdW5d}~XYnXzt|j }Wn,t k r}ztdW5d}~XYnX|r|n|} | sdS| } | | d||||| d| IdHS)Nzos.sendfile() is not availableznot a regular filer) r|sendfileAttributeErrorrSendfileNotAvailableErrorr=ioUnsupportedOperationfstatst_sizer?r`_sock_sendfile_native_impl) r rufileoffsetcountrIr=rfsize blocksizefutrrr_sock_sendfile_nativeJs2    z,_UnixSelectorEventLoop._sock_sendfile_nativec Cs,|} |dk r|||r4||||dS|rd||}|dkrd||||||dSzt| |||} WnDttfk r|dkr| ||| | |j || |||||| Ynbt k rj} z|dk r| j t jkrt| tk rtdt j} | | _| } |dkrBtd} |||||| n|||||| W5d} ~ XYnttfk rYntk r} z|||||| W5d} ~ XYnjX| dkr||||||nD|| 7}|| 7}|dkr | ||| | |j || |||||| dS)Nrzsocket is not connectedzos.sendfile call failed)r= remove_writer cancelled_sock_sendfile_update_filepos set_resultr|rBlockingIOErrorInterruptedError_sock_add_cancellation_callbackZ add_writerrr?rEZENOTCONNrConnectionError __cause__rr set_exceptionrdrerf)r rZ registered_fdrur=rrr total_sentfdsentrInew_excrrrrras               z1_UnixSelectorEventLoop._sock_sendfile_native_implcCs|dkrt||tjdSNr)r|lseekSEEK_SET)r r=rrrrrrsz4_UnixSelectorEventLoop._sock_sendfile_update_fileposcsfdd}||dS)Ncs&|r"}|dkr"|dS)Nr4)rr=r)rrr rurrcbszB_UnixSelectorEventLoop._sock_add_cancellation_callback..cb)add_done_callback)r rrurrrrrsz6_UnixSelectorEventLoop._sock_add_cancellation_callback)N)NN)NN)N)N)N)__name__ __module__ __qualname____doc__rr&r3rKr1r*r9r[r]rprcrrrrrr __classcell__rrr"rr/sH -       . CFrcseZdZdZdfdd ZddZddZd d Zd d Zd dZ ddZ ddZ ddZ e jfddZdddZddZddZZS) rUiNcst|||jd<||_||_||_||_d|_d|_ t |jj }t |st |st |sd|_d|_d|_tdt |jd|j|jj||j|jj|j|j|dk r|jtj|ddS)NrWFz)Pipe transport is for pipes/sockets only.)rr_extra_loop_piper=_fileno _protocol_closing_pausedr|rrrS_ISFIFOrS_ISCHRr> set_blocking call_soonconnection_made _add_reader _read_readyr _set_result_unless_cancelled)r rrWrXrYrZmoder"rrrs:      z_UnixReadPipeTransport.__init__cCs|jjg}|jdkr |dn|jr0|d|d|jt|jdd}|jdk r|dk rt ||jt j }|r|dq|dn |jdk r|dn |dd d |S) Nclosedclosingfd= _selectorpollingidleopen<{}> )r#rrappendrrgetattrrr _test_selector_event selectors EVENT_READformatjoin)r rDr!rrrr__repr__s(         z_UnixReadPipeTransport.__repr__c Cszt|j|j}WnDttfk r,Yntk rX}z||dW5d}~XYn^X|rl|j |nJ|j rt d|d|_|j |j|j |jj|j |jddS)Nz"Fatal read error on pipe transport%r was closed by peerT)r|readrmax_sizerrr? _fatal_errorrZ data_receivedr get_debugr rDr_remove_readerrZ eof_received_call_connection_lost)r r2rIrrrrs  z"_UnixReadPipeTransport._read_readycCs>|js |jrdSd|_|j|j|jr:td|dS)NTz%r pauses reading)rrrrrrr debugr rrr pause_readings   z$_UnixReadPipeTransport.pause_readingcCsB|js |jsdSd|_|j|j|j|jr>td|dS)NFz%r resumes reading) rrrrrrrr rrrrrresume_readings   z%_UnixReadPipeTransport.resume_readingcCs ||_dSrrr rXrrr set_protocol sz#_UnixReadPipeTransport.set_protocolcCs|jSrrrrrr get_protocolsz#_UnixReadPipeTransport.get_protocolcCs|jSrrrrrr is_closingsz!_UnixReadPipeTransport.is_closingcCs|js|ddSr)r_closerrrrr&sz_UnixReadPipeTransport.closecCs,|jdk r(|d|t|d|jdSNzunclosed transport r$rr-r&r _warnrrr__del__s z_UnixReadPipeTransport.__del__Fatal error on pipe transportcCsZt|tr4|jtjkr4|jrLtjd||ddn|j||||j d| |dSNz%r: %sTexc_info)message exceptionrrX) rRr?rEZEIOrrr rcall_exception_handlerrrr rIrrrrrs z#_UnixReadPipeTransport._fatal_errorcCs(d|_|j|j|j|j|dSNT)rrrrrrr rIrrrr-sz_UnixReadPipeTransport._closecCs4z|j|W5|jd|_d|_d|_XdSrrr&rrZconnection_lostrrrrr2s  z,_UnixReadPipeTransport._call_connection_lost)NN)r)rrrrrrrrrrrrr&r+r,rrrrrrrr"rrUs rUcseZdZd%fdd ZddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZejfddZddZd&dd Zd'd!d"Zd#d$ZZS)(r\Nc st||||jd<||_||_||_t|_d|_ d|_ t |jj }t|}t|}t|} |s|s| sd|_d|_d|_tdt |jd|j|jj|| s|rtjds|j|jj|j|j|dk r|jtj|ddS)NrWrFz?Pipe transport is only for pipes, sockets and character devicesZaix)rrrrr=rr bytearray_buffer _conn_lostrr|rrrrrrr>rrrrr'platform startswithrrr r) r rrWrXrYrZrZis_charZis_fifoZ is_socketr"rrr?s:        z _UnixWritePipeTransport.__init__cCs|jjg}|jdkr |dn|jr0|d|d|jt|jdd}|jdk r|dk rt ||jt j }|r|dn |d| }|d|n |jdk r|dn |dd d |S) Nrrrrrrzbufsize=rrr)r#rrrrrrrr rr EVENT_WRITEget_write_buffer_sizerr)r rDr!rrlrrrrds,         z _UnixWritePipeTransport.__repr__cCs t|jSr)lenrrrrrr |sz-_UnixWritePipeTransport.get_write_buffer_sizecCs6|jrtd||jr*|tn|dS)Nr)rrr rDrrBrokenPipeErrorrrrrrs   z#_UnixWritePipeTransport._read_readyc CsRt|tttfstt|t|tr.t|}|s6dS|jsB|jrj|jtj krXt d|jd7_dS|j s8zt |j|}Wntttfk rd}YnZttfk rYnBtk r}z$|jd7_||dWYdSd}~XYnX|t|kr dS|dkr&t||d}|j|j|j|j |7_ |dS)Nz=pipe closed by peer or os.write(pipe, data) raised exception.rr#Fatal write error on pipe transport)rRbytesr memoryviewr{reprrrrZ!LOG_THRESHOLD_FOR_CONNLOST_WRITESr warningrr|writerrrrdrerfrr rZ _add_writer _write_readyZ_maybe_pause_protocol)r r2nrIrrrrs8      z_UnixWritePipeTransport.writec Cs|jstdzt|j|j}Wnttfk r:Ynttfk rRYnt k r}z6|j |j d7_ |j |j||dW5d}~XYnhX|t|jkr|j |j |j||jr|j |j|ddS|dkr |jd|=dS)NzData should not be emptyrr r)rr{r|rrrrrdrerfr.rr_remove_writerrr Z_maybe_resume_protocolrrr)r rrIrrrrs,    z$_UnixWritePipeTransport._write_readycCsdSrrrrrr can_write_eofsz%_UnixWritePipeTransport.can_write_eofcCsB|jr dS|jstd|_|js>|j|j|j|jddSr) rrr{rrrrrrrrrr write_eofs z!_UnixWritePipeTransport.write_eofcCs ||_dSrrrrrrrsz$_UnixWritePipeTransport.set_protocolcCs|jSrrrrrrrsz$_UnixWritePipeTransport.get_protocolcCs|jSrrrrrrrsz"_UnixWritePipeTransport.is_closingcCs|jdk r|js|dSr)rrrrrrrr&sz_UnixWritePipeTransport.closecCs,|jdk r(|d|t|d|jdSrrrrrrrs z_UnixWritePipeTransport.__del__cCs|ddSr)rrrrrabortsz_UnixWritePipeTransport.abortrcCsNt|tr(|jr@tjd||ddn|j||||jd||dSr) rRr?rrr rrrrrrrrrs  z$_UnixWritePipeTransport._fatal_errorcCsFd|_|jr|j|j|j|j|j|j|j|dSr) rrrrrr.rrrrrrrrs  z_UnixWritePipeTransport._closecCs4z|j|W5|jd|_d|_d|_XdSrrrrrrrs  z-_UnixWritePipeTransport._call_connection_lost)NN)r)N)rrrrrr rrrrrrrrr&r+r,rrrrrrrrr"rr\<s"% #   r\c@seZdZddZdS)rac Ksd}|tjkrt\}}zPtj|f||||d|d||_|dk rh|t|d|d|j_ d}W5|dk r||XdS)NF)rhrirjrkuniversal_newlinesrlwb) buffering) subprocessPIPEr~ socketpairr&Popen_procrdetachri) r rHrhrirjrkrlrmZstdin_wrrr_start s.  z_UnixSubprocessTransport._startN)rrrr"rrrrra srac@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS)raHAbstract base class for monitoring child processes. Objects derived from this class monitor a collection of subprocesses and report their termination or interruption by a signal. New callbacks are registered with .add_child_handler(). Starting a new process must be done within a 'with' block to allow the watcher to suspend its activity until the new process if fully registered (this is needed to prevent a race condition in some implementations). Example: with watcher: proc = subprocess.Popen("sleep 1") watcher.add_child_handler(proc.pid, callback) Notes: Implementations of this class must be thread-safe. Since child watcher objects may catch the SIGCHLD signal and call waitpid(-1), there should be only one active object per process. cGs tdS)aRegister a new child handler. Arrange for callback(pid, returncode, *args) to be called when process 'pid' terminates. Specifying another callback for the same process replaces the previous handler. Note: callback() must be thread-safe. NNotImplementedErrorr rrrGrHrrrrb9s z&AbstractChildWatcher.add_child_handlercCs tdS)zRemoves the handler for process 'pid'. The function returns True if the handler was successfully removed, False if there was nothing to remove.Nr#r rrrrrremove_child_handlerDsz)AbstractChildWatcher.remove_child_handlercCs tdS)zAttach the watcher to an event loop. If the watcher was previously attached to an event loop, then it is first detached before attaching to the new loop. Note: loop may be None. Nr#r rrrr attach_loopLsz AbstractChildWatcher.attach_loopcCs tdS)zlClose the watcher. This must be called to make sure that any underlying resource is freed. Nr#rrrrr&VszAbstractChildWatcher.closecCs tdS)zReturn ``True`` if the watcher is active and is used by the event loop. Return True if the watcher is installed and ready to handle process exit notifications. Nr#rrrrr_]szAbstractChildWatcher.is_activecCs tdS)zdEnter the watcher's context and allow starting new processes This function must return selfNr#rrrr __enter__fszAbstractChildWatcher.__enter__cCs tdS)zExit the watcher's contextNr#r abcrrr__exit__lszAbstractChildWatcher.__exit__N) rrrrrbr'r)r&r_r*r/rrrrr"s   rcCs2t|rt| St|r*t|S|SdSr)r| WIFSIGNALEDWTERMSIG WIFEXITED WEXITSTATUS)statusrrr_compute_returncodeqs     r5c@sDeZdZddZddZddZddZd d Zd d Zd dZ dS)BaseChildWatchercCsd|_i|_dSr)r _callbacksrrrrrszBaseChildWatcher.__init__cCs|ddSr)r)rrrrr&szBaseChildWatcher.closecCs|jdk o|jSr)rZ is_runningrrrrr_szBaseChildWatcher.is_activecCs tdSrr#)r expected_pidrrr _do_waitpidszBaseChildWatcher._do_waitpidcCs tdSrr#rrrr_do_waitpid_allsz BaseChildWatcher._do_waitpid_allcCs~|dkst|tjst|jdk r<|dkr<|jr %d)r|rFrGrHr5rLr7rIrMrNrMrrr rr)r rrr4rsrGrHrrrr:<s@    z FastChildWatcher._do_waitpid_all) rrrrrr&r*r/rbr'r:rrrr"rrs  rc@sheZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZdS)ra~A watcher that doesn't require running loop in the main thread. This implementation registers a SIGCHLD signal handler on instantiation (which may conflict with other code that install own handler for this signal). The solution is safe but it has a significant overhead when handling a big number of processes (*O(n)* each time a SIGCHLD is received). cCsi|_d|_dSr)r7_saved_sighandlerrrrrrzszMultiLoopChildWatcher.__init__cCs |jdk Sr)rOrrrrr_~szMultiLoopChildWatcher.is_activecCsT|j|jdkrdSttj}||jkr:tdnttj|jd|_dS)Nz+SIGCHLD handler was changed by outside code) r7r.rOr; getsignalr<r=r r)r rQrrrr&s     zMultiLoopChildWatcher.closecCs|Srrrrrrr*szMultiLoopChildWatcher.__enter__cCsdSrrr exc_typeexc_valexc_tbrrrr/szMultiLoopChildWatcher.__exit__cGs&t}|||f|j|<||dSr)rget_running_loopr7r9)r rrrGrHrrrrrbsz'MultiLoopChildWatcher.add_child_handlercCs*z|j|=WdStk r$YdSXdSr?r@r&rrrr's z*MultiLoopChildWatcher.remove_child_handlercCsN|jdk rdSttj|j|_|jdkrTr)r:rdrerfr r)r rrrrrr=s  zMultiLoopChildWatcher._sig_chldN)rrrrrr_r&r*r/rbr'r)r:r9r=rrrrrgs %rc@sneZdZdZddZddZddZdd Zd d Zd d Z e j fddZ ddZ ddZddZddZdS)raAThreaded child watcher implementation. The watcher uses a thread per process for waiting for the process finish. It doesn't require subscription on POSIX signal but a thread creation is not free. The watcher has O(1) complexity, its performance doesn't depend on amount of spawn processes. cCstd|_i|_dSr) itertoolsr _pid_counter_threadsrrrrrs zThreadedChildWatcher.__init__cCsdSrrrrrrr_szThreadedChildWatcher.is_activecCs |dSr) _join_threadsrrrrr&szThreadedChildWatcher.closecCs.ddt|jD}|D] }|qdS)z%Internal: Join all non-daemon threadscSsg|]}|r|js|qSr)is_alivedaemon.0threadrrr sz6ThreadedChildWatcher._join_threads..N)r)rZvaluesr)r threadsr`rrrr[sz"ThreadedChildWatcher._join_threadscCs|Srrrrrrr*szThreadedChildWatcher.__enter__cCsdSrrrQrrrr/szThreadedChildWatcher.__exit__cCs6ddt|jD}|r2||jdt|ddS)NcSsg|]}|r|qSr)r\r^rrrra sz0ThreadedChildWatcher.__del__..z0 has registered but not finished child processesr$)r)rZrbr#r-)r rrcrrrrs  zThreadedChildWatcher.__del__cGsFt}tj|jdt|j||||fdd}||j|<|dS)Nzwaitpid-T)targetnamerHr]) rrUrJThreadr9nextrYrZstart)r rrrGrHrr`rrrrbs  z&ThreadedChildWatcher.add_child_handlercCsdSrrr&rrrr'sz)ThreadedChildWatcher.remove_child_handlercCsdSrrr(rrrr)sz ThreadedChildWatcher.attach_loopcCs|dks tzt|d\}}Wn(tk rH|}d}td|Yn Xt|}|rhtd||| rtd||n|j |||f||j |dS)NrrBrCrDrV) r{r|rFrHr rr5rrrWrqrZrI)r rr8rGrHrrr4rsrrrr9"s(  z ThreadedChildWatcher._do_waitpidN)rrrrrr_r&r[r*r/r+r,rrbr'r)r9rrrrrs  rcsHeZdZdZeZfddZddZfddZdd Z d d Z Z S) _UnixDefaultEventLoopPolicyz:UNIX event loop policy with a watcher for child processes.cstd|_dSr)rr_watcherrr"rrrAs z$_UnixDefaultEventLoopPolicy.__init__c CsHtj8|jdkr:t|_tttjr:|j|j j W5QRXdSr) rrLrjrrRrJcurrent_thread _MainThreadr)_localrrrrr _init_watcherEs z)_UnixDefaultEventLoopPolicy._init_watchercs6t||jdk r2tttjr2|j|dS)zSet the event loop. As a side effect, if a child watcher was set before, then calling .set_event_loop() from the main thread will call .attach_loop(loop) on the child watcher. N)rset_event_looprjrRrJrkrlr)r(r"rrroMs   z*_UnixDefaultEventLoopPolicy.set_event_loopcCs|jdkr||jS)z~Get the watcher for child processes. If not yet set, a ThreadedChildWatcher object is automatically created. N)rjrnrrrrr^[s z-_UnixDefaultEventLoopPolicy.get_child_watchercCs4|dkst|tst|jdk r*|j||_dS)z$Set the watcher for child processes.N)rRrr{rjr&)r rnrrrset_child_watcheres  z-_UnixDefaultEventLoopPolicy.set_child_watcher) rrrrrZ _loop_factoryrrnror^rprrrr"rri=s   ri)2rrErrXr|rr;r~rrr'rJr+rrrrrrr r r r logr __all__r ImportErrorrZBaseSelectorEventLooprZ ReadTransportrUZ_FlowControlMixinZWriteTransportr\ZBaseSubprocessTransportrarr5r6rrrrZBaseDefaultEventLoopPolicyrirrrrrrs`             NO5Ji}Y3