U í·€gˆãM@sªdZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZddlmZz ddlZWnek rdZYnXddl Z ddl m!Z!ddl m"Z"dd l m#Z#dd l m$Z$dd l m%Z%dd l m&Z&dd l m'Z'ddl m(Z(ddl)m*Z*ddl)m+Z+ddl)m,Z,ddl)m-Z-ddl)m.Z.ddl/m0Z0ddl/m1Z1ddl/m2Z2ddl/m3Z3ddl/m4Z4ddl/m5Z5ddl/m6Z6zddlm7Z7Wn<ek r`e 8¡e 9d¡ddl7Z7W5QRXYnXe0rrddl:Z:n ddl;ZdZ:e&rddld?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjgMZ>dkej?kZ@de jAkZBdle jAkpVdme jAkZCeBp`eCZDdne jAkZEdoe jAkZFe"r¤eCr¤eGdpƒZHdqeH I¡kZJW5QRXndrZJejKdskZLe  M¡dtkZNe,dudv„ƒZOe#ræeOƒdwkZPeOƒdxkZQndrZPdrZQdyZRdzZSd{ZTd|ZUeDr$eRd}9ZReUd}9ZUeSd~9ZSeTd}9ZTe jVdkr>d€e  W¡ZXn de  W¡ZXd‚ZYe0rbdƒ Zd„d…¡Z[nd†Z[e \¡ ]¡d‡kZ^e j_ `e j_ ae j_ bec¡dˆdˆ¡¡Zde jA ed‰e j_ aeddŠ¡¡Zfe j_ `e j_ bec¡¡Zgehe jid‹ƒZjehe dŒƒZkehe jidƒZlehe dŽƒZmehe jidƒZnehe jidƒZoe&oe' Zpehe d‘ƒZqehe jid’ƒZrehe jid“ƒZsehe jid”ƒZtehe d•ƒZuzeuo\eve  w¡ƒZxWneyk rzdrZxYnXehe d–ƒZzehe d—ƒZ{ehe jid˜ƒZ|e#s¨e!o²e  }¡dkZ~d™dš„Zeƒ\Z€ZeGe j‚d›ƒZƒe „eƒj…¡dœd„e†e ƒDƒZ‡eˆedže‰ƒƒZŠe‹ƒZŒe‹ƒZGdŸdH„dHejŽƒZd d¡„Zedâd¢dE„ƒZ‘ed£dG„ƒZ’d¤dF„Z“ed¥dB„ƒZ”ed¦d§„ƒZ•ej–eUfd¨dC„Z—dãd©dD„Z˜dªdZ„Z™d«dY„ZšGd¬d­„d­ƒZ›e›e jœdeUd®d¯d°d\„ƒZe›e2ežfdeUd®d¯däd²d]„ƒZŸe›eždeUd®d¯d³d[„ƒZ d´dU„Z¡dµd¶„Z¢ej£d·dT„ƒZ¤d¸dV„Z¥dåd¹dW„Z¦dæd»dX„Z§Gd¼dS„dSƒZ¨edkrúus-asciiÚasciiz..ZPSUTIL_SCRIPTS_DIRÚscriptsÚ cpu_affinityÚcpu_freqÚenvironÚ getloadavgÚioniceÚ memory_mapsÚnet_io_countersÚcpu_numÚ io_countersÚrlimitÚsensors_batteryÚ sensors_fansÚsensors_temperaturesÚthreadscCsàdd„}tj ¡}ttddƒ}trFtjdkrF|dk rFtj|d<||fStrTtj|fSt r²|tjƒpœ|tj   tj¡ƒpœ|t dtjdd…ƒƒpœ|t  ¡ ¡ƒ}|sªtdƒ‚||fStj   tj¡}tj  |¡sÔt|ƒ‚||fSdS) NcSs>ztj|dgtjtjdWntjk r4YdSX|SdS)Nz-V)ÚstdoutÚstderr)r{Ú check_callÚPIPEÚCalledProcessError)Úexerrr‚Úattempt÷sÿ z_get_py_exe..attemptÚ_base_executable)r‡éÚ__PYVENV_LAUNCHER__z python%s.%srmz"can't find python exe real abspath)Úosr‘ÚcopyÚgetattrr}r Ú version_infor~rjrÚpathÚrealpathrÚpsutilÚProcessr¢Ú ValueErrorÚexistsÚAssertionError)r£rsÚbaser¢rrr‚Ú _get_py_exeös,     ÿþür³zr+cCs g|]}| d¡rtt|ƒ‘qS)ZSTATUS_©Ú startswithr©r­©Ú.0Úxrrr‚Ú $s r¹ÚAF_UNIXcsPeZdZdZ‡fdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z ‡Z S)rGz6A thread task which does nothing expect staying alive.cs$tƒ ¡d|_d|_t ¡|_dS)NFçü©ñÒMbP?)rÚ__init__Ú_runningÚ _intervalÚ threadingÚEventÚ_flag©Úself©Ú __class__rr‚r¼5s zThreadTask.__init__cCs|jj}d||jt|ƒfS)Nz<%s running=%s at %#x>)rÅÚ__name__r½Úid©rÃÚnamerrr‚Ú__repr__;szThreadTask.__repr__cCs | ¡|S©N)ÚstartrÂrrr‚Ú __enter__?szThreadTask.__enter__cOs | ¡dSrË)Ústop)rÃÚargsÚkwargsrrr‚Ú__exit__CszThreadTask.__exit__cCs(|jrtdƒ‚tj |¡|j ¡dS)zStart thread and keep it running until an explicit stop() request. Polls for shutdown every 'timeout' seconds. zalready startedN)r½r¯r¿ÚThreadrÌrÁÚwaitrÂrrr‚rÌFs zThreadTask.startcCs(d|_|j ¡|jr$t |j¡qdS)NT)r½rÁÚsetÚtimeÚsleepr¾rÂrrr‚ÚrunOs zThreadTask.runcCs |jstdƒ‚d|_| ¡dS)z8Stop thread execution and and waits until it is stopped.zalready stoppedFN)r½r¯ÚjoinrÂrrr‚rÎUszThreadTask.stop) rÆÚ __module__Ú __qualname__Ú__doc__r¼rÊrÍrÑrÌr×rÎÚ __classcell__rrrÄr‚rG2s  cst ˆ¡‡fdd„ƒ}|S)Ncs.z ˆ||ŽWStk r(tƒ‚YnXdSrË)Ú ExceptionrC©rÏrЩÚfunrr‚Úwrappercs  z&_reap_children_on_err..wrapper©Ú functoolsÚwraps©ràrárrßr‚Ú_reap_children_on_errbsræcKsÞ| dt¡| dt¡| dt ¡¡| dt¡trHd}| d|¡|dkr¸tt ¡d}zLt|ƒd d |d }td |g}t j |f|Ž}t   |¡t |d d dW5t|ƒXn"t j |f|Ž}t   |¡t|jƒ|S)aCreate a python subprocess which does nothing for some secs and return it as a subprocess.Popen instance. If "cmd" is specified that is used instead of python. By default stdin and stdout are redirected to /dev/null. It also attempts to make sure the process is in a reasonably initialized state. The process is registered for cleanup on reap_children(). ÚstdinrÚcwdrséÚ creationflagsN©Údirz import time;zopen(r'%s', 'w').close();z&[time.sleep(0.1) for x in range(100)];rpT©ÚdeleteÚempty)Ú setdefaultrr§Úgetcwdr$r rWrTr#r{ÚPopenÚ_subprocesses_startedÚaddr\r[Úpid)ÚcmdÚkwdsZCREATE_NO_WINDOWÚtestfnZpylineÚsprocrrr‚rDns4    ÿþÿ     cCs¬d}tt ¡d}zzt dtj |¡tf¡}t rDt |dd\}}n t |ƒ\}}t   |j ¡}tt|dddƒ}t |¡t   |¡}||fW¢St|ƒ|dk r¦t|ƒXdS) aCreate a subprocess which creates another one as in: A (us) -> B (child) -> C (grandchild). Return a (child, grandchild) tuple. The 2 processes are fully initialized and will live for 60 secs and are registered for cleanup on reap_children(). NrëaV import subprocess, os, sys, time s = "import os, time;" s += "f = open('%s', 'w');" s += "f.write(str(os.getpid()));" s += "f.close();" s += "[time.sleep(0.1) for x in range(100 * 6)];" p = subprocess.Popen([r'%s', '-c', s]) p.wait() r)rêTFrí)rWr§rñrTÚtextwrapÚdedentr«Úbasenamer#r rAr­r®rõryr\Ú _pids_startedrô)ÚtfilerøÚsÚsubpÚchildZgrandchild_pidZ grandchildrrr‚rF˜s" ÷      csÜtjs t‚tƒ}t d|¡}d}t|ƒ}zŠ|  t ¡t |ƒ\}}|  ¡\}}zXt   | ¡gggt ¡t| d¡ƒ}t |¡t |¡‰t‡fdd„ƒ|ˆfW¢W¢S| ¡XW5| ¡t|ƒ|dk rÖt|ƒXdS)z±Create a zombie process and return a (parent, zombie) process tuple. In order to kill the zombie parent must be terminate()d first, then zombie must be wait()ed on. a import os, sys, time, socket, contextlib child_pid = os.fork() if child_pid > 0: time.sleep(3000) else: # this is the zombie process s = socket.socket(socket.AF_UNIX) with contextlib.closing(s): s.connect('%s') if sys.version_info < (3, ): pid = str(os.getpid()) else: pid = bytes(str(os.getpid()), 'ascii') s.sendall(pid) Nécsˆ ¡tjkSrË)Ústatusr­Ú STATUS_ZOMBIEr©Úzombierr‚Úáózspawn_zombie..)r­r r±rWrúrûraÚcloserTÚ settimeoutrrAÚacceptÚselectÚfilenoryÚrecvrýrôr®rZ)Z unix_fileÚsrcrþÚsockÚparentÚconnÚ_Zzpidrrr‚rE¿s. ñ     c Ksˆ| dd¡| dd¡tƒ}zFt|dƒ}| |¡W5QRXtt|jgf|Ž}t|jƒ||fWSt k r‚t |ƒ‚YnXdS)zRun python 'src' code string in a separate interpreter. Returns a subprocess.Popen instance and the test file where the source code was written. rNržÚw) rðrWÚopenÚwriterDr#rÉr[rõrÝrT)rr÷ÚsrcfileÚfrrrr‚rAìs     cKsÊtrdnd}| dtj¡| dtj¡| dd¡| d|¡t|tƒrTt |¡}tj|f|Ž}t   |¡t r‚|j t d\}}n |  ¡\}}|jdkr¤t||ƒ‚|r°t|ƒ| d ¡rÆ|d d …}|S) zURun cmd in a subprocess and return its output. raises RuntimeError on error. rérrržrtTrê©ÚtimeoutÚ Néÿÿÿÿ)r rðr{r Ú isinstanceÚstrÚshlexrzròrórôrÚ communicaterÚ returncodeÚ RuntimeErrorrgÚendswith)rör÷ÚflagsÚprržrrr‚Úshs&           r&c sòdd„‰dd„‰‡‡‡fdd„}‡‡‡fdd„‰‡fd d „}d d „}|}zbt|tƒrb|||ƒW¢LSt|tjtjfƒr‚ˆ||ƒW¢,St|tjƒrœ|||ƒW¢St d |ƒ‚W5t|tjtjfƒrÆ||ƒt|tƒrÔ|n|j}t |¡rìt|ƒ‚XdS)a˜Terminate a process and wait() for it. Process can be a PID or an instance of psutil.Process(), subprocess.Popen() or psutil.Popen(). If it's a subprocess.Popen() or psutil.Popen() instance also closes its stdin / stdout / stderr fds. PID is wait()ed even if the process is already gone (kills zombies). Does nothing if the process does not exist. Return process exit status. cSsdt|tjƒrts| ¡n | |¡tr`t|tjƒr`zt |j¡ |¡WStj k r^YnXdSrË) rr{ròrrÓr r­r®rõÚ NoSuchProcess©Úprocrrrr‚rÓ's  zterminate..waitcSs6trtrtj}tr(|tjkr(| tj¡| |¡dSrË)rrjÚsignalÚSIGKILLr Ú send_signalÚSIGCONT)r)Úsigrrr‚Úsendsig3s  zterminate..sendsigc sZzˆ|ˆƒWn@tk rN}z"tr0|jdkr0n|jtjkr>‚W5d}~XYnXˆ||ƒS)Né)ÚOSErrorr ÚwinerrorÚerrnoZESRCH)r)rÚerr©r/r.rÓrr‚Úterm_subprocess_proc=s z'terminate..term_subprocess_proccs0zˆ|ˆƒWntjk r$YnXˆ||ƒSrË)r­r'r(r5rr‚Úterm_psutil_procGs z#terminate..term_psutil_proccsFzt |¡}Wn(tjk r6tr2t||ƒYSYn Xˆ||ƒSdSrË)r­r®r'r r)rõrr))r7rr‚Úterm_pidNs zterminate..term_pidcSs4|jr|j ¡|jr |j ¡|jr0|j ¡dSrË)rr ržrç)r)rrr‚Ú flush_popenXs   zterminate..flush_popenz wrong type %rN) rr{ròr­ryrõÚ pid_existsr±r®Ú TypeError)Z proc_or_pidr.Ú wait_timeoutr6r8r9r%rõr)r/r.r7rÓr‚rBs&        cCst ¡j|d}tr&t ¡}t|ƒqtrr?rrõr%rÚaliverrr‚rCrs    cCs¬ts tdƒ‚d}t ¡d}|D]"}| ¡s4|dkr>||7}q qDq |sTtd|ƒ‚d}d}| d¡}t|dƒ}t|ƒdkrŠt|dƒ}t|ƒdkr¢t|dƒ}|||fS) z"Return a tuple such as (2, 6, 36).z not POSIXÚrmrlzcan't parse %rrér‡) r ÚNotImplementedErrorr§ÚunameÚisdigitr¯rzryÚlen)rÿrFÚcÚminorÚmicroZnumsÚmajorrrr‚rY—s&         cCsbts tdƒ‚t ¡}t|dƒr*|jp&d}n&t d|d¡}|rLt|  d¡ƒnd}|d|d|fS)Nz not WINDOWSÚservice_pack_majorrz\s\d$rˆrD) r rEr}ÚgetwindowsversionÚhasattrrMÚreÚsearchryÚgroup)ZwvÚspÚrrrr‚rX¯s  c@s<eZdZdZeddddfdd„Zdd„Zdd „Zd d „ZdS) ÚretryzA retry decorator.Nr»cCs2|r|rtdƒ‚||_||_||_||_||_dS)Nz/timeout and retries args are mutually exclusive)r¯Ú exceptionrÚretriesÚintervalÚlogfun)rÃrVrrWrXrYrrr‚r¼Ãszretry.__init__ccsT|jr*t ¡|j}t ¡|krPdVqn&|jrHt|jƒD] }dVq:ndVqHdSrË)rrÕrWr)rÃÚstop_atrrrr‚Ú__iter__Ós   zretry.__iter__cCs|jdk rt |j¡dSrË)rXrÕrÖrÂrrr‚rÖßs z retry.sleepcs"t ˆ¡‡‡fdd„ƒ}ˆ|_|S)Nc s|d}ˆD]b}zˆ||ŽWSˆjk rh}z,|}ˆjdk rHˆ |¡ˆ ¡WY¢qW5d}~XYqXqtrv|‚n‚dSrË)rVrYrÖr)rÏrÐÚexcr©ràrÃrr‚ráäs  zretry.__call__..wrapper)rãräÚ decorator)rÃràrárr]r‚Ú__call__ãszretry.__call__) rÆrÙrÚrÛrÝr¼r[rÖr_rrrr‚rUÀsú  rUr»)rVrYrrXcCs$|t ¡krt |¡‚t |¡dS)z„Wait for pid to show up in the process list then return. Used in the test suite to give time the sub process to initialize. N)r­Úpidsr'r®©rõrrr‚r[ûs  Tc Cs:t|dƒ}| ¡}W5QRX|s*|s*t‚|r6t|ƒ|S)z8Wait for a file to be written on disk with some content.Úrb)rÚreadr±rT)ÚfnamerîrïrÚdatarrr‚r\ s cCs|ƒ}|st‚|S)z1Keep calling function until it evaluates to True.)r±)ràÚretrrr‚rZscCsndd„}zLt |¡}t |j¡r0t tj|¡}nt tj|¡}t rJ|ƒn||ƒWnt k rhYnXdS)z?Convenience function for removing temporary test files or dirs.c Ss~t ¡t}t ¡|krvz|ƒWStk r4Yn6tk rh}z|}tdt|ƒƒW5d}~XYnXt d¡q |‚dS)Nz ignoring %sg{®Gáz„?)rÕrrZ WindowsErrorrgrrÖ)ràrZrr4rrr‚Ú retry_fun0s  " zsafe_rmpath..retry_funN) r§ÚstatÚS_ISDIRÚst_moderãÚpartialÚshutilÚrmtreeÚremover r)r«rgÚstràrrr‚rT-s   cCs(zt |¡Wntk r"YnXdS)z.Convenience function for creating a directory.N)r§Úmkdirrrërrr‚Ú safe_mkdirOsrqc cs.t ¡}zt |¡dVW5t |¡XdS)z@Context manager which temporarily changes the current directory.N)r§rñrS)ÚdirnameÚcurdirrrr‚rSWs   cCsRtj |¡rt|ƒ‚t t|¡t t |¡t rNt  |¡}t  ||j t jB¡|S)z6Create a Python executable file in the given location.)r§r«r°r±ÚatexitÚregisterrTrlÚcopyfiler#r rhÚchmodrjÚS_IEXEC)r«rorrr‚rUbs   c Cs¨tj |¡rt|ƒ‚tdƒs&t d¡‚|dkr:t d¡}nt |t ƒsLt|ƒ‚t   t |¡ttdddƒ}| |¡W5QRXzt d|jd|g¡W5t |jƒX|S) z5Create a compiled C executable in the given location.Úgcczgcc is not installedNz‡ #include int main() { pause(); return 1; } z.c©Úsuffixrz-o)r§r«r°r±rÚpytestÚskiprúrûrrrtrurTrrWrrÉr{rŸ)r«Zc_coderrrr‚rVms    rCcCs>tjt||d}tj |¡stj |¡}t t |¡|SqdS)zîReturn an absolute pathname of a file or dir that did not exist at the time this call is made. Also schedule it for safe deletion at interpreter exit. It's technically racy but probably not really due to the time variant. )Úprefixr{rìN) ÚtempfileÚmktempr'r§r«r°r¬rtrurT)r{rìrÉr«rrr‚rW‡s    c@sTeZdZdZedd„ƒZeddd„ƒZeddd„ƒZedd d „ƒZGd d „d ƒZ dS)rRzéA class that mimics some basic pytest APIs. This is meant for when unit tests are run in production, where pytest may not be installed. Still, the user can test psutil installation via: $ python3 -m psutil.tests cOs4t ¡ t¡}tjdd |¡tjdtdd|S)z‚Mimics pytest.main(). It has the same effect as running `python3 -m unittest -v` from the project root directory. rm)Ú verbosityz.ExceptionInfoNcSs|jSrË)Ú_excrÂrrr‚Úvalue·sz/fake_pytest.raises..ExceptionInfo.value)rÆrÙrÚrŠÚpropertyr‹rrrr‚Ú ExceptionInfo´srNc 3svˆƒ}z |VWnT|k rd}z6|rNt |t|ƒ¡sNd |t|ƒ¡}t|ƒ‚||_W5d}~XYnXtd|ƒ‚dS)Nz"{}" does not match "{}"z %r not raised)rPrQrÚformatr±rŠ)r\ÚmatchZeinfor4Úmsg©rrr‚Úcontext»s z#fake_pytest.raises..context)r)N)Ú contextlibÚcontextmanager)r\rr’rr‘r‚Úraises°s zfake_pytest.raisescCs"|rt ¡ ||¡St ¡ |¡S)zMimics `pytest.warns`.)rHÚTestCaseZassertWarnsRegexZ assertWarns)Úwarningrrrr‚ÚwarnsÊszfake_pytest.warnsrCcCst |¡‚dS)zMimics `unittest.SkipTest`.N)rHZSkipTest©Úreasonrrr‚r}Ñszfake_pytest.skipc@s(eZdZeddd„ƒZGdd„dƒZdS)zfake_pytest.markrCcCs t ||¡S)z'Mimics `@pytest.mark.skipif` decorator.)rHZskipIf)Ú conditionršrrr‚ÚskipifØszfake_pytest.mark.skipifc@s"eZdZdZddd„Zdd„ZdS)zfake_pytest.mark.xdist_groupz4Mimics `@pytest.mark.xdist_group` decorator (no-op).NcCsdSrËrrÈrrr‚r¼àsz%fake_pytest.mark.xdist_group.__init__cCs|SrËr)rÃZ cls_or_methrrr‚r_ãsz%fake_pytest.mark.xdist_group.__call__)N)rÆrÙrÚrÛr¼r_rrrr‚Ú xdist_groupÝs rN)rC)rÆrÙrÚÚ staticmethodrœrrrrr‚ÚmarkÖs rŸ)N)N)rC) rÆrÙrÚrÛržr‰r•r˜r}rŸrrrr‚rRšs    c@s&eZdZes"dd„Zejdd„ƒZdS)r–cCsdSrËrrÂrrr‚ÚrunTestïszTestCase.runTestcos dVdSrËr)rÃrÏrˆrrr‚ÚsubTestòszTestCase.subTestN)rÆrÙrÚrr r“r”r¡rrrr‚r–ësr–c@sZeZdZdZddd„Zdd„Zdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z dS)rMzžTest class providing auto-cleanup wrappers on top of process test utilities. All test classes should derive from this one, even if we use pytest. rCNcCst||d}| t|¡|S)N)r{rì)rWÚ addCleanuprT)rÃr{rìrdrrr‚rWs  zPsutilTestCase.get_testfncOst||Ž}| t|¡|SrË)rDr¢rB)rÃrÏr÷rùrrr‚rDs  zPsutilTestCase.spawn_testproccCs*tƒ\}}| t|¡| t|¡||fSrË)rFr¢rB)rÃZchild1Zchild2rrr‚rF s   z"PsutilTestCase.spawn_children_paircCs*tƒ\}}| t|¡| t|¡||fSrË)rEr¢rB)rÃrrrrr‚rEs   zPsutilTestCase.spawn_zombiecOs*t||Ž\}}| t|¡| t|¡|SrË)rAr¢rTrB)rÃrÏr÷rùrrrr‚rAs  zPsutilTestCase.pyruncCsˆt|tjƒst‚|j|jks t‚|j|jks0t‚|jr@|js@t‚t|tjƒrt|j|j ks\t‚|jdk rt|jdkstt‚t |ƒt |ƒdS©Nr) rr­ÚErrorr±rõrÉÚ_nameÚ ZombieProcessÚppidZ_ppidrÚrepr)rÃr)r\rrr‚Ú_check_proc_excs   zPsutilTestCase._check_proc_excc Cs¦t tj¡4}zt |¡Wntjk r:tdƒ‚YnXW5QRX|jj|ksVt‚|jj dksft‚t  |¡rxt|ƒ‚|t  ¡ksˆt‚|dd„t  ¡Dƒks¢t‚dS)Nz&wasn't supposed to raise ZombieProcesscSsg|] }|j‘qSrrar¶rrr‚r¹5sz0PsutilTestCase.assertPidGone..) r|r•r­r'r®r¦r±r‹rõrÉr:r`Ú process_iter)rÃrõÚcmrrr‚Ú assertPidGone+szPsutilTestCase.assertPidGonec Cs¾| |j¡t|ƒ}|j|jddD]ˆ\}}|j||dlz |ƒ}WnFtjk r^‚YnDtjk rŒ}z|  ||¡W5d}~XYnXd||f}t |ƒ‚W5QRXq$|j dddS)NT©Ú clear_cache©r)rÉz-Process.%s() didn't raise NSP and returned %rrr) r¬rõrNÚiterÚallr¡r­r¦r'r©r±rÓ)rÃr)ÚnsràrÉrfr\rrrr‚ÚassertProcessGone7s   þz PsutilTestCase.assertProcessGonec Csdt |j¡}||kst‚ts4ts4t|ƒt|ƒks4t‚| ¡tjksFt‚|  ¡sRt‚t  |j¡sbt‚|  ¡|jt  ¡ks|t‚|jdd„t  ¡Dƒks˜t‚it_|jdd„t  ¡Dƒksºt‚t|ƒ}|j|jddD]f\}}|j||dJz |ƒWn8tjtjfk r,}z| ||¡W5d}~XYnXW5QRXqÒtrÊt tj¡}| ¡W5QRX| ||j¡t tj¡}| ¡W5QRX| ||j¡t tj¡}| ¡W5QRX| ||j¡| ¡| ¡| ¡|  ¡|  ¡søt‚t  |j¡s t‚|jt  ¡kst‚|jdd„t  ¡Dƒks.cSsg|] }|j‘qSrrar¶rrr‚r¹]sTr­r¯cSsg|] }|j‘qSrrar¶rrr‚r¹yscSsg|] }|j‘qSrrar¶rrr‚r¹{s)!r­r®rõr±r r ÚhashrrÚ is_runningr:Úas_dictr`rªZ_pmaprNr°r±r¡r¦Ú AccessDeniedr©rr|r•Úcmdliner‹r¢r”ÚsuspendÚresumerBÚkill)rÃr)Úcloner²ràrÉr\r«rrr‚ÚassertProcessZombieJsN    *z"PsutilTestCase.assertProcessZombie)rCN) rÆrÙrÚrÛrWrDrFrErAr©r¬r³r½rrrr‚rMüs   zunreliable on PYPYr™c@s¤eZdZdZdZdZdZer dndZdZ e   ¡Z e e d¡ƒZedd „ƒZed d „ƒZd d „Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zddd„Zdd„ZdS) rLaçTest framework class for detecting function memory leaks, typically functions implemented in C which forgot to free() memory from the heap. It does so by checking whether the process memory usage increased before and after calling the function many times. Note that this is hard (probably impossible) to do reliably, due to how the OS handles memory, the GC and so on (memory can even decrease!). In order to avoid false positives, in case of failure (mem > 0) we retry the test for up to 5 times, increasing call repetitions each time. If the memory keeps increasing then it's a failure. If available (Linux, OSX, Windows), USS memory is used for comparison, since it's supposed to be more precise, see: https://gmpy.dev/blog/2016/real-process-memory-and-environ-in-python If not, RSS memory is used. mallinfo() on Linux and _heapwalk() on Windows may give even more precision, but at the moment are not implemented. PyPy appears to be completely unstable for this framework, probably because of its JIT, so tests on PYPY are skipped. Usage: class TestLeaks(psutil.tests.TestMemoryLeak): def test_fun(self): self.execute(some_function) éÈrnrr†TZ PSUTIL_DEBUGcCst d¡dS)NF)r­Ú _set_debug©Úclsrrr‚Ú setUpClassµszTestMemoryLeak.setUpClasscCst |j¡dSrË)r­r¿Ú_psutil_debug_origrÀrrr‚Ú tearDownClass¹szTestMemoryLeak.tearDownClasscCs|j ¡}t|d|jƒS)NZuss)Ú _thisprocÚmemory_full_infor©Zrss)rÃÚmemrrr‚Ú_get_mem½s zTestMemoryLeak._get_memcCstr|j ¡S|j ¡SdSrË)r rÅÚnum_fdsÚ num_handlesrÂrrr‚Ú _get_num_fdsÃs zTestMemoryLeak._get_num_fdscCs|jrt|dtjddS)NÚyellow)ÚcolorÚfile)Úverboserr}rž)rÃrrrr‚Ú_logÉszTestMemoryLeak._logcCsx| ¡}| |¡| ¡}||}|dkr8| d|¡‚|dkrttrHdnd}|dkr\|d7}d|||f}| |¡‚dS) z»Makes sure num_fds() (POSIX) or num_handles() (Windows) does not increase after calling a function. Used to discover forgotten close(2) and CloseHandle syscalls. rzHnegative diff %r (gc probably collected a resource from a previous test)ÚfdÚhandlerDrÿz%s unclosed %s after calling %rN)rËÚcallÚfailr )rÃràÚbeforeÚafterÚdiffÚtype_rrrr‚Ú _check_fdsÍs  ÿÿ zTestMemoryLeak._check_fdscCs^tjdd| ¡}t|ƒD]}| |¡}~~qtjdd| ¡}tjgksRt‚||}|S)z€Get 2 distinct memory samples, before and after having called fun repeatedly, and return the memory difference. rD)Z generation)ÚgcZcollectrÈrrÓÚgarbager±)rÃràÚtimesZmem1r¸rfZmem2r×rrr‚Ú _call_ntimesâs    zTestMemoryLeak._call_ntimesc Cs¶g}d}|}td|dƒD]†}| ||¡} d|t| ƒt| |ƒ|f} | | ¡| |kp^| |k} | r||dkrv| | ¡dS|dkrŠtƒ| | ¡||7}| }q| d |¡¡‚dS)NrrDz,Run #%s: extra-mem=%s, per-call=%s, calls=%sz. )rrÝrÚappendrÐÚprintrÔrØ) rÃràrÜrWÚ toleranceÚmessagesZprev_memZincreaseÚidxrÇrÚsuccessrrr‚Ú _check_memñs.  ü   zTestMemoryLeak._check_memcCs|ƒSrËr)rÃràrrr‚rÓ szTestMemoryLeak.callNc Csè|dk r |n|j}|dk r|n|j}|dk r0|n|j}|dk rB|n|j}zD|dksZtdƒ‚|dksjtdƒ‚|dksztdƒ‚|dksŠtdƒ‚Wn.tk rº}ztt|ƒƒ‚W5d}~XYnX| ||¡| |¡|j ||||ddS) zTest a callable.NrDztimes must be >= 1rzwarmup_times must be >= 0zretries must be >= 0ztolerance must be >= 0)rÜrWrà) rÜÚ warmup_timesrWràr±r¯rrÝrÙrä)rÃràrÜrårWràr4rrr‚Úexecutesÿ  zTestMemoryLeak.executec s"‡‡‡fdd„}ˆj|f|ŽdS)znConvenience method to test a callable while making sure it raises an exception on every call. csˆ ˆˆ¡dSrË)Z assertRaisesr©r\ràrÃrr‚rÓ+sz*TestMemoryLeak.execute_w_exc..callN)ræ)rÃr\ràrÐrÓrrçr‚Ú execute_w_exc&szTestMemoryLeak.execute_w_exc)NNNN)rÆrÙrÚrÛrÜråràr*rWrÏr­r®rÅÚboolr§ÚgetenvrÃÚ classmethodrÂrÄrÈrËrÐrÙrÝrärÓrærèrrrr‚rLŒs2   ÿ cCs®ddl}ddl}ddl}ddl}ddl}z ddl}Wntk rLd}YnXz ddl}Wntk rrd}YnX| ¡}t j r˜t dƒr˜t dƒ|d<nzt j r´dt ¡d|d<n^t jrúdd ttt ¡ƒ¡|d<ttdƒrø|dd t ¡7<nd t ¡t ¡f|d<d  tt ¡ƒt ¡g¡|d <t jrJt ¡d |d <d  t ¡t ¡t  ¡g¡|d<t!|ddƒ|d<|dk rš|dd|j"7<t jròt dƒrÐt ddgƒ}t|ƒ #d¡d|d<nd|d<t $¡d} | rò| |d<t% &¡|d<| '¡} d| d| df|d<|j (t  )¡¡ *d¡|d<|j +¡ *d¡|d<| ,¡|d<t-j. /d¡|d <t- 0¡|d!<t1|d"<t 2¡|d#<t- 3¡|d$<t  4¡|d%<d&t5d'd(„t  6¡Dƒƒ|d)<t  7¡} d*t8| j9ƒt:| j;ƒt:| j<ƒf|d+<t  =¡} d*t8| j9ƒt:| j;ƒt:| j<ƒf|d,<t>t  ?¡ƒ|d-<t  @¡ A¡} |  Bd.d¡| C| ¡|d/<tDd0t%jEd1| F¡D]$\}}tDd2|d3|ft%jEd1qbtDd0t%jEd1t%jG H¡t%jG H¡dS)4NrÚ lsb_releasezlsb_release -d -sZOSz Darwin %szWindows ú Ú win32_editionz, z%s %sÚarchrmZkernelÚpythonÚ __version__z not installedÚpipz (wheel=%s)ryz --versionrrDÚglibcz fs-encodingz%s, %sÚlangz%Y-%m-%d %H:%M:%Sz boot-timerÕÚuserú~ÚhomerèZpyexeÚhostnameZPIDZcpusz%.1f%%, %.1f%%, %.1f%%cSsg|]}|t ¡d‘qS)éd)r­Ú cpu_countr¶rrr‚r¹{sz!print_sysinfo..Zloadavgz%s%%, used=%s, total=%sZmemoryÚswapr`r”r)zF======================================================================©rÎz%-17s %sú:)IÚ collectionsÚdatetimeÚgetpassÚlocaleÚpprintròÚ ImportErrorÚwheelÚ OrderedDictr­rrr&ZOSXrurvr rØrxrÚ win32_verrOrîÚsystemr€ÚlistÚ architectureÚmachiner rFÚpython_implementationÚpython_versionÚpython_compilerr©rñrzÚlibc_verr}ÚgetfilesystemencodingÚ getlocaleÚ fromtimestampÚ boot_timeÚstrftimeÚnowÚgetuserr§r«Ú expanduserrñr#ÚnodeÚgetpidrúrwr’Úvirtual_memoryryÚpercentrÚusedÚtotalÚ swap_memoryrHr`r®r¶r@ÚpformatrßržÚitemsrÚflush)rþrÿrrrròrÚinfoÚoutrÿrôrÇrûZpinfoÚkÚvrrr‚rP1sª     ÿý      ÿþ     ÿý ý    cCs8tdd„ƒ}z|ƒ|dkWStk r2YdSXdS)NcSsXi}tdƒ}| ¡dd…D]6}dd„| d¡Dƒ}|dt|dƒ}}|||<q|S)Nztasklist.exe /NH /FO csvrDcSsg|]}| dd¡‘qS)ú"rC)Úreplacer¶rrr‚r¹¤sz@is_win_secure_system_proc..get_procs..ú,r)r&Ú splitlinesrzry)rfr"ÚlineÚbitsrÉrõrrr‚Ú get_procsŸs z,is_win_secure_system_proc..get_procsz Secure SystemF)rÚKeyError)rõr+rrr‚rQs  cCs6t ¡}t|dƒr| ¡St|dƒr2t | ¡¡SdS)Nr–rr)r­r®rOr–ÚrandomÚchoicer)r%rrr‚Ú_get_eligible_cpu¯s   r/c@sJeZdZdZddifddifgZddifddddifd difd difd difd difd difddifddifddifg Zddifddifddifddifddifddifddifddifddddifddifddifddifd difd!difd"difd#difd$difgZerNed%difg7Zed&difg7Zed'difg7Zed(difg7Zerded)difg7Ze rzed*difg7Ze r”ed+e j fifg7Ze rªed,difg7ZerÀed-difg7ZerÖed.difg7Zerìed/difg7Zered0dd1d2ifg7ZgZer"eddifg7Znede jfifg7Ze rRed+e j d3fifg7Ze rŠerved*e jd4fifg7Zned*e jfifg7Ze r¦ed,eƒgfifg7Zd5ejfifd6difd7difd8difd9difgZered5ejfifg7Zed5ejfifg7ZeeeeZd:d;„ZdEdd?„Z e!d@dA„ƒZ"e!dBdC„ƒZ#dDS)FrNaA container that lists all Process class method names + some reasonable parameters to be called with. Utility methods (parent(), children(), ...) are excluded. >>> ns = process_namespace(psutil.Process()) >>> for fun, name in ns.iter(ns.getters): ... fun() Ú cpu_percentrZmemory_percentr¶r?r>TÚ connectionsrµZmemory_info_exZoneshotrÚparentsrõrÓ©rr¸Ú cpu_timesZ create_timerèr¢rÆZ memory_inforÉÚnet_connectionsÚkindr±ÚniceZnum_ctx_switchesZ num_threadsZ open_filesr§rrœÚusernameZuidsZgidsZterminalrÉr—r“r˜rr–r‘rÊr”ÚgroupedF)rirr,r¹rºrBr»cCs ||_dSrË)Ú_proc)rÃr)rrr‚r¼szprocess_namespace.__init__ccsZt|ƒ}t |¡|D]>\}}}|r,| ¡t|j|ƒ}tj|f|ž|Ž}||fVqdS©z_Given a list of tuples yields a set of (fun, fun_name) tuples in random order. N)rr-Úshuffler®r©r:rãrk)rÃÚlsr®Úfun_namerÏr÷ràrrr‚r°s  zprocess_namespace.itercCs|jj|jjdddS)z&Clear the cache of a Process instance.T)Z _ignore_nspN)r:Ú_initrõrÂrrr‚r®&szprocess_namespace.clear_cachecCs>|D]4\}}}d|}t||ƒsd|jj|f}t|ƒ‚qdS)z}Given a TestCase instance and a list of tuples checks that the class defines the required test method names. Ztest_z$%r class should define a '%s' methodN)rOrÅrÆÚAttributeError)rÁZ test_classr=r>rÚ meth_namerrrr‚Útest_class_coverage*s þz%process_namespace.test_class_coveragecCs`tdd„|jDƒƒ}tdd„|jDƒƒ}tdd„ttjƒDƒƒ}||B|A}|r\td|ƒ‚dS)NcSsg|] }|d‘qSr3rr¶rrr‚r¹:sz*process_namespace.test..cSsg|] }|d‘qSr3rr¶rrr‚r¹;scSsg|]}|ddkr|‘qS)rrrr¶rrr‚r¹<s z!uncovered Process class names: %r)rÔr±Úignoredrìr­r®r¯)rÁÚthisrCÚklassZleftoutrrr‚Útest8s  zprocess_namespace.testN)T)$rÆrÙrÚrÛÚutilsrCÚgettersr r1r2r5r­Z RLIMIT_NOFILEr.r4r0r r3ZsettersZNORMAL_PRIORITY_CLASSrZIOPRIO_CLASS_NONEZ IOPRIO_NORMALr/r*ÚSIGTERMZkillersZ CTRL_C_EVENTZCTRL_BREAK_EVENTr±r¼r°r®rërBrFrrrr‚rN¸s¢  ö ï û  c@sºeZdZdZddifddddifddddifddifd dd difd dd difd dd difd dddifde ¡fifddddifddifddifddddifde ¡fifddifddifddifddifgZeröe râe   ¡dkrâneddd difg7Ze r eddifg7Ze r"eddifg7Zer8eddifg7ZerNed difg7Zerted!difg7Zed"d#ifg7Zd$difd%e ¡gfifd&difd'difgZeZed(d)„ƒZejZd*S)+rOzÝA container that lists all the module-level, system-related APIs. Utilities such as cpu_percent() are excluded. Usage: >>> ns = system_namespace >>> for fun, name in ns.iter(ns.getters): ... fun() rrrúZlogicalFTZ cpu_statsr4ZpercpuZdisk_io_countersZperdiskZdisk_partitionsr±Ú disk_usager5r6Z net_if_addrsZ net_if_statsr•Zpernicr:r`rZusersrÚarm64rr’r›ršr™Zwin_service_iterZwin_service_get)ÚalgrªrAr0Zcpu_times_percentccsLt|ƒ}t |¡|D]0\}}}tt|ƒ}tj|f|ž|Ž}||fVqdSr;)rr-r<r©r­rãrk)r=r>rÏr÷ràrrr‚r°ys   zsystem_namespace.iterN)rÆrÙrÚrÛr§rñrrHr/rrur ÚHAS_GETLOADAVGr9r8r6r r­r®rCr±ržr°rNrBrrrr‚rOBsX         îü cCsdd„}ttd||dS)zZDecorator which runs a test function and retries N times before actually failing. cSstd|tjddS)Nz %r, retryingrü)rßr}rž)r\rrr‚rYsz retry_on_failure..logfunN)rVrrWrY)rUr±)rWrYrrr‚rKˆsÿcs‡fdd„}|S)z,Decorator to Ignore AccessDenied exceptions.cst ˆ¡‡‡fdd„ƒ}|S)Ncs@z ˆ||ŽWStjk r:ˆdk r,ˆs,‚t d¡‚YnXdS)Nzraises AccessDenied)r­r·r|r}rÞ©ràÚonly_ifrr‚rá™s z9skip_on_access_denied..decorator..wrapperrârå©rOrßr‚r^˜s z(skip_on_access_denied..decoratorr©rOr^rrPr‚rI•s cs‡fdd„}|S)z3Decorator to Ignore NotImplementedError exceptions.cst ˆ¡‡‡fdd„ƒ}|S)NcsHz ˆ||ŽWStk rBˆdk r*ˆs*‚dˆj}t |¡‚YnXdS)Nz4%r was skipped because it raised NotImplementedError)rErÆr|r})rÏrÐrrNrr‚rá¬s ÿÿz;skip_on_not_implemented..decorator..wrapperrârårPrßr‚r^«s z*skip_on_not_implemented..decoratorrrQrrPr‚rJ¨s ú 127.0.0.1c Cs@t t ¡¡(}| |df¡| ¡dW5QR£SQRXdS)z6Return an unused TCP port. Subject to race conditions.rrDN)r“ÚclosingÚsocketÚbindÚ getsockname)Úhostrrrr‚r_ÅscCsˆ|dkr|tthkrd}t ||¡}z@tjdkrB| tjtjd¡| |¡|tj kr`|  d¡|WSt k r‚|  ¡‚YnXdS)zBinds a generic socket.N©rCr>ÚcygwinÚntrDr†) rrrTr§rÉÚ setsockoptÚ SOL_SOCKETÚ SO_REUSEADDRrUrÚlistenrÝr )ÚfamilyÚtypeÚaddrrrrr‚r`Ìs     cCsrtjs t‚tj |¡rt|ƒ‚t tj|¡}z"| |¡|tj krL|  d¡Wnt k rl|  ¡‚YnX|S)zBind a UNIX socket.r†) r­r r±r§r«r°rTrºrUrr^rÝr )rÉr`rrrr‚raÝs   rXc Cs´t t |t¡¡˜}| |¡| d¡| ¡}t |t¡}zJ| |¡| ¡}| ¡\}}||krz||fWW5QR£S|  ¡qPWnt k r¤|  ¡‚YnXW5QRXdS)z^Build a pair of TCP sockets connected to each other. Return a (server, client) tuple. r†N) r“rSrTrrUr^rVÚconnectr r r1)r_raZllrIZcaddrÚarrr‚rbìs     cCs’tjs t‚d}}z@t|tjd}| d¡t tjtj¡}| d¡| |¡Wn6t k rˆ|dk rr|  ¡|dk r‚|  ¡‚YnX||fS)zƒBuild a pair of UNIX sockets connected to each other through the same UNIX file name. Return a (server, client) tuple. N©r`r) r­r r±rarTrÚ setblockingrºrbrÝr )rÉÚserverÚclientrrr‚rcs   c csìg}d}}z¨| ttjtjƒ¡| ttjtjƒ¡tƒrd| ttj tjƒ¡| ttj tjƒ¡t r¬t r¬t ƒ}t ƒ}t |ƒ\}}t|tjd}|||fD]}| |¡qœ|VW5|D] }| ¡qº||fD]}|dk rÐt|ƒqÐXdS)z1Open as many socket families / types as possible.Nrd)r rTrÞr`rTrrÚ SOCK_DGRAMrrr r:rWrcra)ÚsocksZfname1Zfname2rÿrdÚs1Ús2Zs3rrr‚rds*     cCsddl}tr(tr(ts(t|tjƒs(t|ƒ‚|tjkršdd„|  d¡Dƒ}t |ƒdksZt|ƒ‚|D]"}d|krvdks^nt|ƒ‚q^tsŽt |ƒ}|  |¡nd|tj krÎt|tƒs¶t|ƒ‚tsÂt |ƒ}| |¡n0|tjkròt d|¡dk sþt|ƒ‚n td |ƒ‚dS) z[Check a net address validity. Supported families are IPv4, IPv6 and MAC addresses. rNcSsg|] }t|ƒ‘qSr)ryr¶rrr‚r¹>sz%check_net_address..rlrˆéÿz([a-fA-F0-9]{2}[:|\-]?){6}zunknown family %r)Ú ipaddressÚenumrr"rÚIntEnumr±rTrrzrHrÚ IPv4AddressrrÚ IPv6Addressr­ZAF_LINKrPrr¯)rar_rmZoctsÚnumrrr‚r]5s&       cCsTdd„}dd„}dd„}dd„}d d „}||ƒ||ƒ||ƒ||ƒ||ƒd S) z*Check validity of a connection namedtuple.cSsÔt|ƒdk}t|ƒdks$tt|ƒƒ‚|d|jksr0r¥rrDrmr‡rˆr†r0) rHr±rÑr_r`ÚladdrÚraddrrrõ)rZhas_pidrrr‚Ú check_ntupleSs z-check_connection_ntuple..check_ntuplec Ssð|jttthkst|jƒ‚tdk r:t|jtjƒsNt|ƒ‚nt|jtƒsNt|ƒ‚|jtkrÌt   |j|j ¡}t   |¡Rz|  |jddf¡Wn2t jk r¾}z|jtjkr®‚W5d}~XYnXW5QRXn |jtkrì|jtjksìt|jƒ‚dSr£)r_rrrºr±rnrroryrTr`r“rSrUrsÚerrorr3Z EADDRNOTAVAILrr­Ú CONN_NONE)rrÿr4rrr‚Ú check_family_s     z-check_connection_ntuple..check_familycSs†ttdtƒƒ}|jtjtj|hks,t|jƒ‚tdk rLt|jtj ƒs`t|ƒ‚nt|jt ƒs`t|ƒ‚|jtjkr‚|j t j ks‚t|j ƒ‚dS)NÚSOCK_SEQPACKET)r©rTÚobjectr`rrhr±rnrroryrr­rw)rryrrr‚Ú check_typetsýü z+check_connection_ntuple..check_typecSs¬|j|jfD]š}|jtthkr†t|tƒs4tt|ƒƒ‚|s:q t|j t ƒsTtt|j ƒƒ‚d|j krjdksvnt|j ƒ‚t |j |jƒq |jt kr t|tƒs tt|ƒƒ‚q dS)Nriÿÿ)rsrtr_rrrrwr±r`Úportryr]Úiprºr)rrarrr‚Ú check_addrsƒs" z,check_connection_ntuple..check_addrscSs†t|jtƒst|jƒ‚dd„ttƒDƒ}|j|ks.check_status..) rrrr±rìr­r_rrr`rrw)rZvalidsrrr‚Ú check_statussÿz-check_connection_ntuple..check_statusNr)rrurxr{r~rrrr‚Úcheck_connection_ntuplePs   r€cCsLg}|D]>}tr<|jtjkræsz is_namedtuple..)r`Ú __bases__rHrwr©rr±)r¸ÚtÚbrrrr‚riÝs  c#sttrdnd‰d‰t|ˆd}‡‡fdd„t ¡ ¡Dƒ}t |¡}t ||¡zt   |¡|VW5t |ƒXdS)zÂCtx manager which picks up a random shared CO lib used by this process, copies it in another location and loads it in memory via ctypes. Return the new absolutized path. Úpypyrðz.sorzcs6g|].}tj |j¡dˆkrˆ|j ¡kr|j‘qS)rD)r§r«r†Úlowerr¶©r¢Úextrr‚r¹ôsþú'copyload_shared_lib..N) r"rWr­r®r”r-r.rlrvrTÚctypesÚCDLL)r{ÚdstÚlibsrrr—r‚rhës   þ    c #sÔddlm}ddlm}d‰t|ˆd}‡fdd„t ¡ ¡Dƒ}trb|sbdd„t ¡ ¡Dƒ}t  |¡}t   ||¡d }zt |¡}|VW5|d k rÆtj j j}|jg|_||jƒ}|dkrÆ|ƒt|ƒXd S) zÖCtx manager which picks up a random shared DLL lib used by this process, copies it in another location and loads it in memory via ctypes. Return the new absolutized, normcased path. r)ÚWinError)Úwintypesz.dllrzcsFg|]>}|j ¡ ˆ¡rdtj |j¡ ¡krd|j ¡kr|j‘qS)rðZwow64)r«r–r#r§rür¶©r˜rr‚r¹s ür™cSs(g|] }dtj |j¡ ¡kr|j‘qS)r•)r§r«rür–r¶rrr‚r¹sþN)ršržrŸrWr­r®r”r"r-r.rlrvÚwindllÚkernel32Ú FreeLibraryZHMODULEZargtypesZ_handlerTZWinDLL) r{ržrŸrœrrÚcfiler£rfrr r‚rhs0    þ þ       cCstdddS)NTr=)rCrrrr‚Úcleanup_test_procs7sr¥cCs t |¡SrË)r}Úexit)r.rrrr‚rArr)N)F)TF)N)rCN)N)N)rR)rX)rC)rC)ÅrÛÚ __future__rrtr“ršr3rãrÚr§rur-rPr rrlr*rTrhr{r}rrúr¿rÕrHr†rrrr|rr­rrrr r r r r Zpsutil._commonrrrrrZpsutil._compatrrrrrrrrÚcatch_warningsÚ simplefilterrnZ unittest2Zpsutil._psposixrÚ__all__Úbuiltin_module_namesr"r‘rrjr*r=r@rrrcr?Úmaxsizer-r r>rƒr;r<r!r r,rrÉrr'r(Údecoder)rr–ZASCII_FSr«r¬rØrrÚ__file__r%Úgetr&r…rOr®r.r/r0rMr2r3r:ZHAS_NET_IO_COUNTERSr4r1r5r6rér™r7rÝr8r9Z HAS_THREADSÚgetuidZ SKIP_SYSCONSr³r#r$Údevnullrrur rìr+r©rzrºrÔrórýrÒrGrærDrFrErAr&rIrBrCrYrXrUr'r[r±r\rZrTrqr”rSrUrVrWrRr–rMrŸrœrLrPrQr/rNrOrKrIrJr_r`rarbrcrdr]r€r^rerfrgrirhr¥rrrr‚Ús^                              Þ-              ÿ ÿ                *   ÿ0  ) &-  V %;ü ü ü "   M %l  F     R  3