JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrJFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr 0idZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZddlmZ ddl Z ddl"Z"ddl"m#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+m0Z0e(rddl1m2Z2gdZ3dejhvZ5de jlvxsde jlvZ7e7Z8de jlvZ9de jlvZ:ejvdkDZ<e jzj}dvZ?e jzdk(Z@e.dZAe%reAdkDZBeAdk\ZCnd ZBd ZCd!ZDd"ZEd#ZFd$ZGe8reDd%zZDeGd%zZGeEd&zZEeFd%zZFd'e jd(ZId)ZJd*jd+d,ZLejj}d-vZNe jljd.xsOe jje jje jjeTd/d/ZUe jjeUd0ZVe jje jjeTZWeXe"jd1ZZeXe"jd2Z[eXe"d3Z\eXe"jd4Z]eXe"jd5Z^e(xre) Z_eXe"d6Z`eXe"jd7ZaeXe"jd8ZbeXe"jd9ZceXe"d:ZdeXe"d;ZeeXe"d<ZfeXe"jd=Zge%xse#xre jdk7Zi edxreje"jZl eXe"d>xreje"jZsd?Ztet\ZuZvewe jd@Zyejeyje{e"Dcgc]}|jdAse}e"|c}Z~e}edBeZeZeZGdCdDZeej _me #eZ eejdE<ejGdFdGejZdHZeddIZedJZdKZedLZedMZej"eGfdNZddOZdPZdQZGdRdSZee"j.deGdTUdVZeeefdeGdTUddWZeee j jfdeGdTUdXZdYZdZZej<d[Zd\Zdd]Zdd^ZGd_d`ejFZe jJjMe5dabe jJjOdcdGdedfeZdgZdhZGdidjZGdkdlZeDfdmZddnZddoZddpZeedfdqZej>fdrZddsZdtZej<duZdvZdwZdxZdyZdzZd{Zd|Ze(rej<dd}Znej<dd~ZejdZe(r ej"ej"dyy#e!$rdZ YBwxYw#em$r8ejejepejd ZlYKwxYw#em$r8ejejepejd ZsYhwxYwcc}w)zTest utilities.N)AF_INET)AF_INET6) SOCK_STREAM)AIX)LINUX)MACOS)NETBSD)OPENBSD)POSIX)SUNOS)WINDOWS) bytes2human)debug)memoize) print_color) supports_ipv6)wait_pid)JDEVNULLGLOBAL_TIMEOUTTOLERANCE_SYS_MEM NO_RETRIESPYPY PYTHON_EXEPYTHON_EXE_ENVROOT_DIR SCRIPTS_DIR TESTFN_PREFIXUNICODE_SUFFIXINVALID_UNICODE_SUFFIX CI_TESTINGVALID_PROC_STATUSESTOLERANCE_DISK_USAGEIS_64BITHAS_CPU_AFFINITY HAS_CPU_FREQ HAS_ENVIRONHAS_PROC_IO_COUNTERS HAS_IONICEHAS_MEMORY_MAPSHAS_PROC_CPU_NUM HAS_RLIMITHAS_SENSORS_BATTERY HAS_BATTERYHAS_SENSORS_FANSHAS_SENSORS_TEMPERATURESHAS_NET_CONNECTIONS_UNIX MACOS_11PLUS MACOS_12PLUSCOVERAGEAARCH64PYTEST_PARALLELpyrun terminate reap_children spawn_subproc spawn_zombiespawn_children_pair ThreadTaskunittestskip_on_access_deniedskip_on_not_implementedretry_on_failureTestMemoryLeakPsutilTestCaseprocess_namespacesystem_namespaceis_win_secure_system_proc fake_pytestchdir safe_rmpath create_py_exe create_c_exe get_testfn get_winverkernel_version call_until wait_for_pid wait_for_filecheck_net_addressfilter_proc_net_connections get_free_port bind_socketbind_unix_sockettcp_socketpairunix_socketpaircreate_sockets reload_moduleimport_module_by_pathwarncopyload_shared_lib is_namedtuple__pypy__GITHUB_ACTIONS CIBUILDWHEEL COVERAGE_RUNPYTEST_XDIST_WORKERl>arm64aarch64riscv64cBtjd}ttt|j ddd}|dk(rWt jtjdddgdd id }ttt|j ddd}|S) Nr.) z-sS-cz-import platform; print(platform.mac_ver()[0])SYSTEM_VERSION_COMPAT0T)envuniversal_newlines) platformmac_vertuplemapintsplit subprocess check_outputsys executable) version_strversions F/opt/hc_python/lib64/python3.12/site-packages/psutil/tests/__init__.py macos_versionr}zs""$Q'KC[..s3BQ789G(!--?   )#.#  C!2!23!7!;<= N)ri) rFriiPiz@psutil--u-ƒőősfutf8surrogateescape>us-asciiasciiPSUTIL_ROOT_DIRz..scripts cpu_affinityenviron getloadavgionice memory_mapsnet_io_counterscpu_num io_countersrlimitsensors_battery sensors_fanssensors_temperaturesthreadscpu_freqc 6d}tjj}ttdd}t r,tj dk\r|tj|d<||fStrtj|fStr|tjxs|tjjtjxsc|tjdjtj ddxs(|tj j#}|s t%d||fStjjtj}tjj'|sJ|||fS)Nc tj|dgtjtj|S#tj$rYywxYw)Nz-V)stdoutstderr)rv check_callPIPECalledProcessError)exes r|attemptz_get_py_exe..attemptsI   ! !d JOOJOO  J,,  s6:AA_base_executable)r__PYVENV_LAUNCHER__z python{}.{}rhz"can't find python exe real abspath)osrcopygetattrrxr version_inforyr_rpathrealpathshutilwhichformatpsutilProcessr ValueErrorexists)rrnbasers r| _get_py_exersI **// C 3*D 1D3##v-$2B&)^^ !"Sy ~~s""  CNN # /rww''78 / 1]1133C3CBQ3GHI / v~~'++-. AB BCxggs~~.ww~~c"'C'"Cxr~zr+STATUS_AF_UNIXceZdZdZedZedZed dZed dZed dZ ed dZ Gd d Z y) rFzA 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 c4d}tj|y)Nc<tjdtdy)Nz._warn_on_exit!s MMN r~)atexitregister)rs r|rzfake_pytest._warn_on_exits   &r~ctjjt}tjdj ||S)zMimics pytest.main(). It has the same effect as running `python3 -m unittest -v` from the project root directory. rh) verbosity)r= TestLoaderdiscoverHERETextTestRunnerrun)argskwsuites r|mainzfake_pytest.main*s; ##%..t4!,007 r~Nc^Gddtjdfd }|||S)zMimics `pytest.raises`.c eZdZdZedZy))fake_pytest.raises..ExceptionInfoNc|jSN)_excselfs r|valuez/fake_pytest.raises..ExceptionInfo.value:s yy r~)__name__ __module__ __qualname__rpropertyrrr~r| ExceptionInfor7sD  ! !r~rc3K} |t|d#|$rF}|r3tj|t|sd|d|d}t|||_Yd}~yd}~wwxYww)Nz not raised"z" does not match ")AssertionErrorresearchstrr)excmatcheinfoerrmsgrs r|contextz#fake_pytest.raises..context>sz!OE < %wk%:;;  !5#c(!;eW$6se1=C(--   !s*A,A,A))rrridrs r|__repr__zThreadTask.__repr__s6~~&&4& $--RXbMCCr~c&|j|Sr)startrs r| __enter__zThreadTask.__enter__s  r~c$|jyr)stop)rrkwargss r|__exit__zThreadTask.__exit__s  r~c|jr tdtjj ||j j y)zStart thread and keep it running until an explicit stop() request. Polls for shutdown every 'timeout' seconds. zalready startedN)rrrThreadrrwaitrs r|rzThreadTask.starts9 ==./ /t$ r~cd|_|jj|jr-tj|j |jr,yy)NT)rrsettimesleeprrs r|rzThreadTask.runs7  mm JJt~~ &mmr~c`|js tdd|_|jy)z8Stop thread execution and and waits until it is stopped.zalready stoppedFN)rrjoinrs r|r!zThreadTask.stops%}}./ /  r~) rrrrrrrr#rrr! __classcell__)rs@r|r<r<s*@' D' r~r<cBtjfd}|S)NcF |i|S#t$r twxYwr) Exceptionr8)rr"funs r|wrapperz&_reap_children_on_err..wrappers/ '' '  O  s   functoolswraps)r1r2s` r|_reap_children_on_errr6s%__S Nr~c |jdt|jdt|jdtj|jdtt rd}|jd||t tj} t|d|d }td |g}tj|fi|}tj|t|d d t||Stj|fi|}tj|t|j|S#t|wxYw) 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(). stdinrcwdrn creationflagsdirzimport time;open(r'z6', 'w').close();[time.sleep(0.1) for x in range(100)];rkTdeleteempty) setdefaultrrgetcwdrr rKrHrrvPopen_subprocesses_startedaddrPrOpid)cmdkwdsCREATE_NO_WINDOWtestfnpylinesprocs r|r9r9s% OOGW%OOHg&OOE299;'OOE>*% )9: { ,   "99  tV,C$$S1D1E ! % %e , &T :   L  --!!%(UYY L  s "AE Ec>d}ttj} tjdtj j |dtd}trt|d\}}nt|\}}tj|j}tt|dd }tj!|tj|}||ft#|| t#|SS#t#|| t#|wwxYw) 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<zl import subprocess, os, sys, time s = "import os, time;" s += "f = open('z', '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'z.', '-c', s]) p.wait() r)r;TFr>)rKrrBtextwrapdedentrbasenamerr r6rrrFrtrP _pids_startedrErH)tfilerJssubpchildgrandchild_pid grandchilds r|r;r;s E BIIK (F OO! WW--f567%&0L1    3KD%(KD%txx(]6$eLM.)^^N3 z"F      F     s CDDctjsJt}tjd|d}d}t |} |j tt|\}}|j\}} tj|jgggtt|jd}tj|tj |t#fd|f|j%|j%t'|| t'|SS#|j%wxYw#|j%t'|| t'|wwxYw)zCreate 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 with socket.socket(socket.AF_UNIX) as s: s.connect('za') pid = bytes(str(os.getpid()), 'ascii') s.sendall(pid) NcFjtjk(Sr)statusr STATUS_ZOMBIE)zombiesr|zspawn_zombie..*sv}}&2F2FFr~)rr rKrNrOrU settimeoutrr6acceptselectfilenortrecvrQrErrNcloserH) unix_filesrcrRsockparentconn_zpidr]s @r|r:r: s7 <<< I //&;'   C E I &D 'c ++-a  MM4;;=/2r> Btyy'D   d #^^D)F F GF# JJL I      JJL I     s%6E xYw#t$r t|wxYw)zRun python 'src' code string in a separate interpreter. Returns a subprocess.Popen instance and the test file where the source code was written. rNrw) rArKopenwriter9rrrOrFr0rH)rfrHsrcfilefrTs r|r6r65s  OOHd#OOHd#lG '3 1 GGCL j!&&1:T:TXXg   G s" BB ]:NFF||q6F?++  V  t Mr~c d d fd} fd fd}d}|} t|tru|||t|tjtjfr||t|tr|n |j }t j |rJ|St|tjtjfru ||t|tjtjfr||t|tr|n |j }t j |rJ|St|tjru|||t|tjtjfr||t|tr|n |j }t j |rJ|Std|#t|tjtjfr||t|tr|n |j }t j |rJ|wxYw)aTerminate 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. c|j|trJt|tjr/ t j |jj|Syy#t j$rYywxYwr) r&r rwrvrCrrrF NoSuchProcess)procrts r|r&zterminate..waitmsd ' z$ (8(89 ~~dhh/44W==:7''  s-A##A98A9ctrtrtj}tr2|tjk7r|j tj |j |yr)rr_signalSIGKILLr send_signalSIGCONT)rsigs r|sendsigzterminate..sendsigvs@ ^..C SFNN*   V^^ , r~c |||S#t$rYt$r}tr|jdk(r d}~wwxYw)N)ProcessLookupErrorOSErrorr winerror)rrtrrrr&s r|term_subprocess_procz'terminate..term_subprocess_procsR  D# D'"" "   3<<1,  s  AA?Ac\ |||S#tj$rYwxYwr)rr)rrtrrr&s r|term_psutil_procz#terminate..term_psutil_procs;  D# D'""##   s ++c tj|}||S#tj$rtrt ||cYSYywxYwr)rrrr r)rFrtrrs r|term_pidzterminate..term_pidsQ 3>>#&D $D'2 2 ## .W-- .s!%A  A c|jr|jj|jr|jj|jr|jjyyr)rrdrr8)rs r| flush_popenzterminate..flush_popensL ;; KK    ;; KK    :: JJ    r~z wrong type ) rwrtrvrCrrF pid_existsr TypeError) proc_or_pidr wait_timeoutrrrr~rFrrr&s ` @@@r|r7r7bs ##3 A / a A|, a***FLL9 : Na%a155$$S).3.))FNNFLL9 :#A|4 a***FLL9 : Na%a155$$S).3.)):++ ,'<8 a***FLL9 : Na%a155$$S).3.)) k!/0 0 a***FLL9 : Na%a155$$S).3.))sG%)2G%"G%G%%A.Ictjj|}tr&tj }t |tr&t r&t j }t |t r&|rd|D]}t |dtj|t\}}|D],}td|dt |tj.yy)aTerminate and wait() any subprocess started by this test suite and any children currently running, ensuring that no processes stick around to hog resources. If recursive is True it also tries to terminate and wait() all grandchildren started by this process.  recursiveN)rrszcouldn't terminate process z; attempting kill())r) rrchildrenrDpopr7rQ wait_procsrr[rr)rrrTrFr~rjalives r|r8r8s~~((9(=H $((*$ !#  A ad +$$X~F5A .qe3FG H aV^^ , r~c|ts tdd}tjd}|D]}|j s|dk(r||z }n|st d|d}d}|j d}t|d}t|dk\rt|d}t|dk\rt|d}|||fS) z"Return a tuple such as (2, 6, 36).z not POSIXr rhrgz can't parse rrr) r NotImplementedErrorrunameisdigitrrurtlen)rSrcminormicronumsmajors r|rMrMs !+.. A HHJqME  99;!s( FA   <y122 E E 773.wrapper$skC///I~~C{{. C(JJL sA/AA)r4r5 decorator)rr1r2s`` r|rzretry.__call__#s-      !r~) rrrrr0rrr*rrr~r|rrs*  &r~rr)rrrtrc|tjvrtj|tj|y)zWait 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)rpidsrr)rFs r|rOrO9s/ &++-""3'' NN3r~ct|d5}|j}ddd|ssJ|r t|S#1swYxYw)z8Wait for a file to be written on disk with some content.rbN)rnreadrH)fnamer?r@rqdatas r|rPrPHsC eT avvx   t E K  s ;Ac|}|sJ|S)z1Keep calling function until it evaluates to True.r)r1rets r|rNrNYs %C J3 Jr~cPd} tj|}tj|jr%t j t j|}n$t j tj|}tr|y||y#t$rYywxYw)z?Convenience function for removing temporary test files or dirs.c6tjtz}tj|kr |S#t$rYn%t$r}|}t d|Yd}~nd}~wwxYwtj dtj|krg`)Nz ignoring g{Gz?)r)rFileNotFoundErrorrr[r*)r1rrjrs r| retry_funzsafe_rmpath..retry_funns ))+.iikG# (u  %  (y&'' ( JJt iikG#s= A*A*A%%A*N) rstatS_ISDIRst_moder4partialrrmtreeremover r)rrstr1s r|rHrHksv"  WWT] << ###FMM48C##BIIt4C  E cN    sB BB B%$B%cN tj|y#t$rYywxYw)z.Convenience function for creating a directory.N)rmkdirFileExistsErrorr<s r| safe_mkdirrs$      s  $$c#Ktj} tj|dtj|y#tj|wxYww)z@Context manager which temporarily changes the current directory.N)rrBrG)dirnamecurdirs r|rGrGs?YY[F   sA!AA!AA!cRtjj|rJ|tjt |t jt|trFtj|}tj||jtjz|S)z6Create a Python executable file in the given location.)rrrrrrHrcopyfilerr rchmodrS_IEXEC)rrs r|rIrIsiww~~d#)T) # OOK& OOJ% WWT] rzzDLL01 Kr~cVtjj|rJ|tjdst j dS|tjd}nt|tsJ|tjt|ttdd5}|j!|ddd t#j$dj&d|gt|j&|S#1swYDxYw#tj&wxYw) z5Create a compiled C executable in the given location.gcczgcc is not installedNz #include int main() { pause(); return 1; } z.csuffixrmz-o)rrrrrr rrNrOrwrrrrHrnrKrorvrr)rc_coderqs r|rJrJsww~~d#)T) # << {{122 ~"&#&..& OOK& j%s +q  ,uaffdD9:AFF K , + AFFs0D #DDD(c tjt||}tjj |s;tjj |}tjt||Sw)zReturn 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. )prefixrr=) tempfilemktemprrrrrrrrH)rr=rrs r|rKrKsU mFLww~~d#77##D)D OOK .K r~cTeZdZdZdZddZdZdZdZdZ d Z d Z d Z d Z d Zy)rBzTest class providing auto-cleanup wrappers on top of process test utilities. All test classes should derive from this one, even if we use pytest. c|jj}|jdsd|z}dj||jj|j S)Nzpsutil.z psutil.tests.z{}.{}.{})rr startswithrr_testMethodName)rfqmods r|__str__zPsutilTestCase.__str__sU)) *#e+E   NN # #    r~NcLt||}|jt||S)N)rr=)rK addCleanuprH)rrr=rs r|rKzPsutilTestCase.get_testfns!&c2  U+ r~cHt|i|}|jt||Sr)r9rr7)rrrHrLs r|r9zPsutilTestCase.spawn_subprocs$t,t,  5) r~c|j|i|} tj|jS#tj$r|j |jwxYwr)r9rrrFrassert_pid_gone)rrr"rLs r| spawn_psproczPsutilTestCase.spawn_psprocs["""D3F3 >>%)), ,##    +  s 30A#c|t\}}|jt||jt|||fSr)r;rr7)rchild1child2s r|r;z"PsutilTestCase.spawn_children_pairs5,.  6*  6*r~c|t\}}|jt||jt|||fSr)r:rr7)rrhr]s r|r:zPsutilTestCase.spawn_zombies4%  6*  6*r~czt|i|\}}|jt||jt||Sr)r6rrHr7)rrrHrLrps r|r6zPsutilTestCase.pyrun s6--w  W-  5) r~ct|tjsJ|j|jk(sJ|j|j k(sJ|jr|jsJt|tj r8|j|jk(sJ|j|jdk\sJt|t|yNr) rwrErrorrFr_name ZombieProcessppid_ppidrrepr)rrrs r|_check_proc_exczPsutilTestCase._check_proc_excs#v||,,,ww$(("""xx4::%%% 8888O8 c6// 088tzz) ))xx#xx1}$} C S r~c tj|}td|d#tj$r tdtj$r)}|j |k(sJ|j JYd}~nd}~wwxYwtj|rJ||tjvsJ|tjDcgc]}|j ncc}wc}vsJy)Nzdid not raise NoSuchProcess ()z&wasn't supposed to raise ZombieProcess) rrrrrrFrrr process_iter)rrFrrxs r|rzPsutilTestCase.assert_pid_gones J>>#&D!#@a!HI I ## K !IJ J## $77c> !>88# ## $ $$S).3.)&++-'''&*=*=*?@*?Q155*?@@@@s&0A?A::A? C!c|j|jt|}|j|jdD]<\}}|j t ||5 |}d|d|}t||jdy#tj$rtj$r}|j||Yd}~nd}~wwxYw ddd#1swYxYw)NT clear_cacherrzProcess.z!() didn't raise NSP and returned rrs) rrFrCiterallsubTestrrrrrrr&)rrnsr1rrrrs r|assert_proc_gonezPsutilTestCase.assert_proc_gone+s TXX& t $T:IC3t948 .%C#4&)7$)--; ! ++++4((s3343 988s6&C%(B/C%&C<CC%CC%%C. cDd}tj|j}||k(sJts%tst st |t |k(sJ|jtjk(sJ|jsJtj|jsJ|j||t|}|j|jdD]2\}}|jt!||5 |ddd4t(rt+j,tj"5}|j/ddd|j'|j0t+j,tj"5}|j3ddd|j'||j0t+j,tj"5}|j5ddd|j'||j0|j7|j9|j;|j=|jsJtj|jsJ||y#tj"tj$f$r}|j'||Yd}~d}~wwxYw#1swY xYw#1swYxYw#1swYWxYw#1swY xYw)Nchtry|jtjvsJ|jtjDcgc]}|jc}vsJit_|jtjDcgc]}|jc}vsJycc}wcc}wr)rrFrrr_pmap)rrs r|assert_in_pidsz9PsutilTestCase.assert_proc_zombie..assert_in_pids?s88v{{}, ,,88v/B/B/DE/D!/DEE EEFL88v/B/B/DE/D!/DEE EE FEs B*B/Trr )rrrFr r r hashr[r\ is_runningras_dictrCr r r rr AccessDeniedrrr rcmdlinerrrsuspendresumer7kill) rrrcloner r1rrcms r|assert_proc_zombiez!PsutilTestCase.assert_proc_zombie>sB Ftxx( u}}6U:e, ,,{{} 4 4444     *** t t $T:IC3t9484E98; v334 5  rxx 0v334 5  rxx 0v334  "5  rxx 0         ***t),,f.A.AB4((s33498545454sT K.J+ K;"L:L+#K+K& K.&K++K..K8 ;LLLr N)rrrrrrKr9rr;r:r6rrrrrr~r|rBrBs?       A&6r~rBzunreliable on PYPYrserial)rceZdZdZdZdZdZerdndZdZ e jZ e ejdZedZed Zd Zd Zd Zd ZdZdZdZ ddZdZy)rAaTest 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) rirrT PSUTIL_DEBUGc.tjdy)NF)r _set_debugclss r| setUpClasszTestMemoryLeak.setUpClasss% r~cBtj|jyr)rr$_psutil_debug_origr%s r| tearDownClasszTestMemoryLeak.tearDownClasss#001r~cd|jj}t|d|jS)Nuss) _thisprocmemory_full_inforrss)rmems r|_get_memzTestMemoryLeak._get_mems)nn--/sE377++r~cvtr|jjS|jjSr)r r-num_fds num_handlesrs r| _get_num_fdszTestMemoryLeak._get_num_fdss+ >>))+ +>>--/ /r~cV|jrt|dtjyy)Nyellow)colorfile)verboserrxr)rrs r|_logzTestMemoryLeak._logs << 8#** = r~c |j}|j||j}||z }|dkrd|d}tj|S|dkDr3trdnd}|dkDr|dz }|d|d |}tj|Sy ) zMakes sure num_fds() (POSIX) or num_handles() (Windows) does not increase after calling a function. Used to discover forgotten close(2) and CloseHandle syscalls. rznegative diff z8 (gc probably collected a resource from a previous test)fdhandlerrSz unclosed z after calling N)r5callr rr )rr1beforeafterdiffrtype_s r| _check_fdszTestMemoryLeak._check_fdss ""$ #!!#v~ !8 )22 ;;s# # !8!DxEax F*UG?3'BC;;s# # r~ctjd|j}t|D]}|j |}~~tjd|j}tj gk(sJ||z }|S)zGet 2 distinct memory samples, before and after having called fun repeatedly, and return the memory difference. r) generation)gccollectr1rr?garbage)rr1timesmem1rrmem2rBs r| _call_ntimeszTestMemoryLeak._call_ntimesst a }}uA))C.C3 a }}zzRd{ r~c g}d}|}td|dzD]}|j||} dj|t| t| |z |} |j | | |kxs| |k} | r|dkDr|j | y|dk(r t |j | ||z }| }tjdj|S)Nrrz,Run #{}: extra-mem={}, per-call={}, calls={}z. ) rrMrrappendr;printr rr,) rr1rJr tolerancemessagesprev_memincreaseidxr0rsuccesss r| _check_memzTestMemoryLeak._check_memsGaK(C##C/C@GGC C%K( C OOC Y&9#/G7IIcN!8G #!')({{499X.//r~c|Srr)rr1s r|r?zTestMemoryLeak.calls u r~Nc||n |j}||n |j}||n |j}||n |j} |dk\sJd|dk\sJd|dk\sJd|dk\sJd |j|||j||j||||y#t$r}t t |d}~wwxYw) zTest a callable.Nrztimes must be >= 1rzwarmup_times must be >= 0zretries must be >= 0ztolerance must be >= 0)rJrrQ) rJ warmup_timesrrQrrrrMrDrW)rr1rJrZrrQrs r|executezTestMemoryLeak.execute s* (4L$:K:K %0'dll!*!6IDNN  'A: 33 3:1$ A&A A$a< 7!7 7<> ;#; ;> #|,  5'YO  'SX& & 's0B,, C5C  Cc :fd}|j|fi|y)znConvenience method to test a callable while making sure it raises an exception on every call. c^ tjdS#$rYywxYw)Nz did not raise )r r)rr1sr|r?z*TestMemoryLeak.execute_w_exc..call&s> A{{cU/##?@@  s $,,N)r[)rrr1r"r?s `` r| execute_w_exczTestMemoryLeak.execute_w_exc!s  A  T$V$r~)NNNN)rrrrrJrZrQr rr:rrr-boolrgetenvr) classmethodr'r*r1r5r;rDrMrWr?r[r^rr~r|rArAs> ELIbAGG Iibii78!!22, 0 >$, 08KOP, %r~rAcTtd} ||dk(S#t$rYywxYw)Nci}td}|jddD]H}|jdDcgc]}|jdd}}|dt |d}}|||<J|Scc}w)Nztasklist.exe /NH /FO csvr,rr r)r splitlinesrureplacert)routlinerbitsrrFs r| get_procsz,is_win_secure_system_proc..get_procs3s|+,NN$QR(D04 3@1AIIc2&D@QT!W#DCH) AsA.z Secure SystemF)rKeyError)rFrjs r|rErE1s=  {3?22 s  ''ctj}t|dr|jSt|dr#t j |j Sy)Nrrr)rrhasattrrrandomchoicer)r~s r|_get_eligible_cpurpCsGAq)yy{ N #}}Q^^-.. r~ceZdZdZddifddifgZddifddddifd difd difd difd difd difddifddifg Zddifddifddifddifddifddifddifddifddddifddifddifddifddifd difd!difd"difd#difgZer$ed$difgz Zed%difgz Zed&difgz Zed'difgz Zer ed(difgz Ze r ed)difgz Ze red*e jfifgz Ze r ed+difgz Zer ed,difgz Zer ed-difgz Zer ed.difgz Zer ed/dd0d1ifgz ZgZer eddifgz Znede j&fifgz Ze red*e jd2fifgz Ze r,ered)e j*d3fifgz Zned)e j,fifgz Ze red+egfifgz Zd4ej2fifd5difd6difd7difd8difgZer(ed4ej6fifgz Zed4ej8fifgz ZeezezezZd9Zd?d:Zd;Z e!d<Z"e!d=Z#y>)@rCaA 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_percentrmemory_percentrrrT connectionsroneshotrhparentsrFr&)rr cpu_times create_timer9rr. memory_infornet_connectionskindr nicenum_ctx_switches num_threads open_filesrr[rusernameuidsgidsterminalr3rrrrrrr4rgroupedF)rYirrrrr7rc||_yr)_proc)rrs r|rzprocess_namespace.__init__s  r~c#Kt|}tj||D]M\}}}|r|jt |j |}t j|g|i|}||fOywz_Given a list of tuples yields a set of (fun, fun_name) tuples in random order. N)listrnshufflerrrr4r)rlsrfun_namerrHr1s r|r zprocess_namespace.itersq"Xr$& HdD  "$**h/C##C7$7$7C/ ! %'sA4A6cf|jj|jjdy)z&Clear the cache of a Process instance.T) _ignore_nspN)r_initrFrs r|rzprocess_namespace.clear_caches! T:r~c|D]>\}}}d|z}t||r|jjd|d}t|y)z}Given a TestCase instance and a list of tuples checks that the class defines the required test method names. test_z class should define a z methodN)rmrrAttributeError)r& test_classrrrj meth_namers r|test_class_coveragez%process_namespace.test_class_coverages] !NHa(*I:y1!++4478!}G-%S))!r~c |jDchc]}|d }}|jDchc]}|d }}ttjDchc] }|ddk7s |}}||z|z }|rt d|ycc}wcc}wcc}w)Nrrjzuncovered Process class names: )r ignoredr=rrr)r&rthisrklassleftouts r|testzprocess_namespace.tests!gg&g!g&!$-A1Q4-/?/q1Q43;/?'>U* >wkJK K  '-?s B B B "B N)T)$rrrrutilsrgettersr r'r(r+r RLIMIT_NOFILEr$r*r&r r)settersNORMAL_PRIORITY_CLASSrIOPRIO_CLASS_NONE IOPRIO_NORMALrprSIGTERMkillers CTRL_C_EVENTCTRL_BREAK_EVENTr rr rrarrrr~r|rCrCLsR $'7R&@ AE B R+t,- B r2 B 2r B B r G B b" B B B R$ B R B0 R R$ B r2 R 2r B R#G& VR$%%VR$%%ZR())YB'((]B+,,Xr2&''X 4 46;<<^R,--YB'((YB'((]B+,,]BE(:;<<G VT2&''Vf::CDD '/G #g -C "; * *LLr~rCceZdZdZddifddddifddddifddifd dd difd dd difd dd difd dddifdej fifddddifddifddifddddifdej fifddifddifddifddifgZere re rn eddd difgz Ze r eddifgz Ze r eddifgz Ze r eddifgz Zer eddifgz Zered difgz Zed!d"ifgz Zd#difd$ej"gfifd%difd&difgZeZed'Zej.Zy())rDzA 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() boot_timer cpu_countlogicalFT cpu_statsrwpercpudisk_io_countersperdiskdisk_partitionsr  disk_usagerzr{ net_if_addrs net_if_statsrpernicrr swap_memoryusersvirtual_memoryrrrrrwin_service_iterwin_service_get)algrrrrcpu_times_percentc#Kt|}tj||D]5\}}}tt|}t j |g|i|}||f7ywr)rrnrrrr4r)rrrrHr1s r|r zsystem_namespace.iter s^ "Xr$& HdD&(+C##C7$7$7C/ !%'sAAN)rrrrrrBgetpidrr%rr4HAS_GETLOADAVGr/r.r,r rrrr r r rCrrr~r|rDrDs b" b9e,- b9d+, b" b8U+, b8T*+ R)T!23 B .   ~r* B0 R R B4 01   ~r* R B "b 2r"%G( W  R(D)9:; ;G\2r*+++R455^R,--&B/00'R011&"566 R )*,b1 B b"% G C " ",??r~rDcbd}tttjjfd||S)zZDecorator which runs a test function and retries N times before actually failing. c@t|dtjy)Nz , retrying)r9)rPrxr)rs r|rz retry_on_failure..logfun s z"4r~N)rrtrr)rrr rr0)rrs r|r@r@s1 5 !6;;#8#89  r~cfd}|S)z,Decorator to Ignore AccessDenied exceptions.cFtjfd}|S)Nc| |i|S#tj$rstjdcYSwxYw)Nzraises AccessDenied)rrr r)rr"r1only_ifs r|r2z9skip_on_access_denied..decorator..wrapper/sI :D+F++&& :&"{{#899  :s  -;;r3r1r2rs` r|rz(skip_on_access_denied..decorator.s%   :  :r~rrrs` r|r>r>+s  r~cfd}|S)z3Decorator to Ignore NotImplementedError exceptions.cFtjfd}|S)Nc |i|S#t$r,sjd}tj|cYSwxYw)Nz2 was skipped because it raised NotImplementedError)rrr r)rr"rr1rs r|r2z;skip_on_not_implemented..decorator..wrapperBs] (D+F++& (&"||&'++{{3'' (s 2AAr3rs` r|rz*skip_on_not_implemented..decoratorAs%   (  (r~rrs` r|r?r?>s" r~ctj5}|j|df|jdcdddS#1swYyxYw)z6Return an unused TCP port. Subject to race conditions.rrN)socketbind getsockname)hostrgs r|rSrS[s8 D 4)!!$ s &AAc||tthvrd}tj||} tjdvr/|j tj tjd|j||tjk(r|jd|S#t$r|jwxYw)zBinds a generic socket.r r>ntcygwinrr) rrrrr setsockopt SOL_SOCKET SO_REUSEADDRrrlistenr0rd)familytypeaddrrgs r|rTrTbs |7H"55 == &D  77* * OOF--v/B/BA F $ 6%% % KKN   s A7B""B=cftjsJtjj |rJ|t j t j |} |j||t jk(r|jd|S#t$r|jwxYw)zBind a UNIX socket.r) rr rrrrrrrrr0rd)rrrgs r|rUrUss <<<ww~~d#)T) # == .D $ 6%% % KKN K   s 5BB0ctj|t5}|j||jd|j }tj|t} |j ||j } |j \}}||k(r ||fcdddS|j6#t$r|jwxYw#1swYyxYw)z^Build a pair of TCP sockets connected to each other. Return a (server, client) tuple. rN) rrrrrconnectr`rdr)rrllrcaddras r|rVrVs v{ +r   ! ~~ MM&+ .  IIdOMMOE))+45=q6 , +    GGI   , +s$A C)=C0CCCC(ctjsJdx}} t|tj}|j dtjtj tj}|j d|j|||fS#t$r&||j||jwxYw)zBuild a pair of UNIX sockets connected to each other through the same UNIX file name. Return a (server, client) tuple. Nrr) rr rUrr setblockingrrr0rd)rserverclients r|rWrWs <<<FV !$V-?-?@1v~~v/A/AB1t F     LLN   LLN s BB/C c#<Kg}dx}} |jttjtjttjtj ft r_|jttjtjttjtj ftr^trXt}t}t|\}}t|tj }|||fD]}|j|||D]}|j||fD]}|t|y#|D]}|j||fD]}|t|wxYww)z1Open as many socket families / types as possible.Nr)extendrTrrr SOCK_DGRAMrrr r0rKrWrUrOrdrH)socksfname1fname2s1s2s3rSrs r|rXrXsN EFV# (:(: ; (9(9 :   ? LLFOOV-?-?@FOOV->->?  -\F\F$V,FB!&v/@/@AB"b\ Q" A GGIf%E E"&A GGIf%E E"&s)FD0E): FF)!F FFcXt|tjsJ||tjk(rs|j dDcgc] }t |}}t|dk(sJ||D]}d|cxkr dkrJ|J|tj|y|tjk(r-t|tsJ|tj|y|tjk(rtj d|J|yt#d|cc}w)z[Check a net address validity. Supported families are IPv4, IPv6 and MAC addresses. rgrrz([a-fA-F0-9]{2}[:|\-]?){6}Nzunknown family )rwenumIntEnumrrrurtr ipaddress IPv4Addressrr IPv6AddressrAF_LINKrrr)rrroctsnums r|rQrQs fdll +3V3 +  $ 301A04yA~#t#~C?s? (D (? (D (?d# 6?? "$$*d*$d# 6>> !xx5t<HN$NH?6*5661sD'crd}d}d}d}d}||||||||||y)z*Check validity of a connection namedtuple.cJt|dk(}t|dvsJt||d|jk(sJ|j|d|jk(sJ|j|d|jk(sJ|j|d|jk(sJ|j|d|j k(sJ|j |d|j k(sJ|j |r$|d |jk(sJ|jyy) Nr>rrrrrhrrrr)rr=rrladdrraddrr[rF)rihas_pids r| check_ntuplez-check_connection_ntuple..check_ntuples d)q.4yF"-CI-"Aw$''!*477*!Aw$++%2t{{2%Aw$))#.TYY.#Aw$**$0djj0$Aw$**$0djj0$Aw$++%2t{{2% 7dhh& 0 0& r~c|jttthvsJ|jt |jt j sJ||jtk(rUtj|j|j5} |j|jddfdddy|jtk(r/|jtj k(sJ|jyy#t$r(}|jtjk7rYd}~xd}~wwxYw#1swYyxYwr)rrrrrwrrrrrrrerrno EADDRNOTAVAILr[r CONN_NONE)rirSrs r| check_familyz-check_connection_ntuple..check_familys{{w'::GDKKG:$++t||4:d:4 ;;' ! t{{DII6!FFDJJqM1-.76 [[G #;;&"2"22 ?DKK ?2$yyE$7$77876s0D9 D D6D1,D91D66D99Ecttdt}|jtjtj |hvsJ|jt |jtjsJ||jtj k(r/|jtjk(sJ|jyy)NSOCK_SEQPACKET) rrobjectrrrrwrrr[rr)rirs r| check_typez+check_connection_ntuple..check_types )968Dyy           99   $))T\\28D82 99)) );;&"2"22 ?DKK ?2 *r~c|j|jfD]}|jtthvrt |t sJt||s>t |jtsJt|jd|jcxkrdksnJ|jt|j|j|jtk(st |trJt|y)Nri)rrrrrrwrrrportrtrQiprr)rirs r| check_addrsz,check_connection_ntuple..check_addrssZZ,D{{w11!$.:T :.!$))S1B4 ?B1DII..9 9.!$''4;;7'!$,8d4j8,-r~c*t|jtsJ|jttDcgc]$}|j dst t|&}}|j|vsJ|j|jtthvrB|jtk(r/|jtjk7sJ|jy|jtjk(sJ|jycc}w)NCONN_) rwr[rr=rrrrrrrrr)rirvalidss r| check_statusz-check_connection_ntuple..check_statuss$++s+8T[[8+(+F  (31q||G7LGFA    {{f$1dkk1$ ;;7H- -$)){2J;;&"2"22 ?DKK ?2;;&"2"22 ?DKK ?2 s DDNr)rirrrr r s r|check_connection_ntuplersH 1@" @ 9 @tr~cg}|D]Y}tr@|jtjk(r#trd|j vrt d|I|j|[|S)ztOur process may start with some open UNIX sockets which are not initialized by us, invalidating unit tests. z/syslogz skipping )r rrrrrrrO)consnewris r|rRrR.sX C T[[FNN2djj0 $() 4  Jr~c,tj|Sr) importlibreload)modules r|rYrYAs   F ##r~c8tjjtjj|d}tj j ||}tj j|}|jj||Sr) rrsplitextrPrutilspec_from_file_locationmodule_from_specloader exec_module)rrspecmods r|rZrZEsk 77  BGG,,T2 3A 6D >> 1 1$ =D .. ) )$ /CKKC Jr~c<tj|tdy)zRaise a warning msg.rhrNr)rs r|r[r[Rs MM#{q1r~ct|}|j}t|dk7s |dturyt |dd}t |tsyt d|DS)z-Check if object is an instance of namedtuple.rrF_fieldsNc3<K|]}t|tywr)rwr).0ns r| z is_namedtuple..`s-1az!S!1s)r __bases__rrrrrwr )rtbrqs r|r]r]WsY QA A 1v{ad%'9d#A a  -1- --r~c#Ktrdnd}d}t||z}tjj Dcgc]Y}t j j|j d|k(r(||j jvr |j [}}tj|}tj|| tj||t|ycc}w#t|wxYww)zCtx 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. pypypythonz.sorrN)rrKrrrrrrlowerrnrorrctypesCDLLrH)rrextdstrlibsrfs r|r\r\es f( -^^%113 3ww'*c1cQVV\\^6K FF3  mmD!S!  KK I     s+ADAC3 -DC8'D8 DDc#Kddlm}ddlm}d}t||z}t j j Dcgc]}|jjj|radtjj|jjvr(d|jjvr |j}}trt|srt j j Dcgc]G}dtjj|jjvr |jI}}tj|}tj ||d } tj"|}||Ttj$j&j(} |j*g| _| |j.} | dk(r|t1|y cc}wcc}w#|Ttj$j&j(} |j*g| _| |j.} | dk(r|t1|wxYww) zCtx 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.dllrr+wow64r*N)r-r3r4rKrrrrr,r|rrPrrnrorrWinDLLwindllkernel32 FreeLibraryHMODULEargtypes_handlerH) rr3r4r/r0rr1rfcfiler9rs r|r\r\}s $# -^^%113 3vv||~&&s+BGG,,QVV4::<<qvv||~- FF3    )5577ARWW--aff5;;==7  mmD!S! MM#&EI $mm44@@ (0(8(8'9 $!%--0!8"*$  ? " $mm44@@ (0(8(8'9 $!%--0!8"*$  s:AI*BG:.I*A G?/I*?HA,I*A#I''I*ctdy)NTr)r8rr~r|cleanup_test_procsr?s D!r~c,tj|Sr)rxexit)rrjs r|r^r^s #r~r)F)TFr)z 127.0.0.1)rr )rrrr-rrr4rGrrrrprnrrarxrrrrrvrxrrNrr) tracebackr=rrrrr  ImportErrorrrrrr r r r r psutil._commonrrrrrpsutil._psposixr__all__builtin_module_namesrrr_r r3r5maxsizer#machiner,r4RISCV64r}r1r2rrr"rrrrdecodergetfilesystemencodingASCII_FSgetrrr,r__file__rrrrmrr$r&rr(r)r0HAS_NET_IO_COUNTERSr*r'r+r,r.r/ HAS_THREADSgetuid SKIP_SYSCONSr_rr-r0rrrP format_excrr%rrrrndevnullrrdr=rrr!rrr(rDrQrFrrmodulesrr%r<r6r9r;r:r6rrr7r8rMrLrrrOrrPrNrHrrrGrIrJrKrrBr rrrArErprCrDr@r>r?rSrTrUrVrWrXrQrrRrYrZr[r]r\r?)rs0r|rWs        & "&((# ZS---!RZZ/O>RZZ3O  RZZ ''2::5 ;;  (    " " $(< < (    )  (  ?X-L ?g-LLL  #' !OJaNA 9299;-q) %,,V5FG $3 $ $ & , , .2G G ::>>+ , 0@0@GGLL*D$71ggll8Y/  ww126>>>:fnni0 . V^^X . &..-8 .Yf&786>>95v~~}= V^^X . f&786>2"6+ABfnni0  2)"))+"2 %H$/Ev/E/E/G*HK6:.J48I3JL)X)] N rzz4  !$F  +1q||I/FGFA  &)VX . U#U#r,  > F'CKK(!!(` &&R##L&R&0 &~~NQ/h-J!066r""        .1       v{{445        D  4 &\X&&\ZD!56h'g%^g%(7g%T$ FLFLRC@C@L(  &:%[t"!' 2 2 .. ##<7(HV &$2 . .**f"" FMM&..">? c< FFFOO%I%%e-AY-A-A-CDEK FOO%I%%e-AY-A-A-CDELpsB[&["\*] ][  [ 9\  \ 9]  ]