o
    adf1                     @   s8  d 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 ddlZddlm	Z	 ddlm
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddlm!Z! ddlm"Z" ddlm#Z# ddlm$Z$ ddlm%Z% ddlm&Z& erd d! Z"d"d# Z'G d$d% d%eZ(e#e)ed&e)eoe d'G d(d) d)e(Z*e)ed*G d+d, d,e*Z+G d-d. d.e(Z,e-d/krdd0l.m/Z/ e/e0 dS dS )1a:	  Notes about unicode handling in psutil
======================================.

Starting from version 5.3.0 psutil adds unicode support, see:
https://github.com/giampaolo/psutil/issues/1040
The notes below apply to *any* API returning a string such as
process exe(), cwd() or username():

* all strings are encoded by using the OS filesystem encoding
  (sys.getfilesystemencoding()) which varies depending on the platform
  (e.g. "UTF-8" on macOS, "mbcs" on Win)
* no API call is supposed to crash with UnicodeDecodeError
* instead, in case of badly encoded data returned by the OS, the
  following error handlers are used to replace the corrupted characters in
  the string:
    * Python 3: sys.getfilesystemencodeerrors() (PY 3.6+) or
      "surrogatescape" on POSIX and "replace" on Windows
    * Python 2: "replace"
* on Python 2 all APIs return bytes (str type), never unicode
* on Python 2, you can go back to unicode by doing:

    >>> unicode(p.exe(), sys.getdefaultencoding(), errors="replace")

For a detailed explanation of how psutil handles unicode see #1040.

Tests
=====

List of APIs returning or dealing with a string:
('not tested' means they are not tested to deal with non-ASCII strings):

* Process.cmdline()
* Process.connections('unix')
* Process.cwd()
* Process.environ()
* Process.exe()
* Process.memory_maps()
* Process.name()
* Process.open_files()
* Process.username()             (not tested)

* disk_io_counters()             (not tested)
* disk_partitions()              (not tested)
* disk_usage(str)
* net_connections('unix')
* net_if_addrs()                 (not tested)
* net_if_stats()                 (not tested)
* net_io_counters()              (not tested)
* sensors_fans()                 (not tested)
* sensors_temperatures()         (not tested)
* users()                        (not tested)

* WindowsService.binpath()       (not tested)
* WindowsService.description()   (not tested)
* WindowsService.display_name()  (not tested)
* WindowsService.name()          (not tested)
* WindowsService.status()        (not tested)
* WindowsService.username()      (not tested)

In here we create a unicode path with a funky non-ASCII name and (where
possible) make psutil return it back (e.g. on name(), exe(), open_files(),
etc.) and make sure that:

* psutil never crashes with UnicodeDecodeError
* the returned path matches
    N)closing)BSD)POSIX)WINDOWS)PY3)super)u)APPVEYOR)ASCII_FS)
CI_TESTING)HAS_CONNECTIONS_UNIX)HAS_ENVIRON)HAS_MEMORY_MAPS)INVALID_UNICODE_SUFFIX)PYPYTESTFN_PREFIX)UNICODE_SUFFIX)PsutilTestCase)bind_unix_socket)chdir)copyload_shared_lib)create_py_exe)
get_testfn)
safe_mkdirsafe_rmpath)	serialrun)skip_on_access_denied)spawn_testproc)	terminatec                 C   s4   ddl m} z|| W S  ty   t  Y d S w )Nr   r   )psutil.testsr   ZWindowsError	traceback	print_exc)pathZrm r%   b/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/psutil/tests/test_unicode.pyr   s   s   
r   c              	   C   s   d}t | d}zGzt| t| t|gd}t||d  t|d  W n ttfy?   Y W |dur9t| t| dS w W |durIt| t| dS |durWt| t| w )z`Return True if both the fs and the subprocess module can
    deal with a unicode file name.
    Nsuffix)cmdz-2FT)	r   r   r   r   shutilcopyfileUnicodeEncodeErrorIOErrorr    )r(   sprocZtestfnr%   r%   r&   try_unicode   s*   

r/   c                       s0   e Zd ZdZe fddZ fddZ  ZS )BaseUnicodeTestNc                    sT   t    d| _d | _| jd ur(t| jsd| _d S t| jd| _t| j d S d S )NFTr'   )r   
setUpClass
skip_tests
funky_namefunky_suffixr/   r   r   )cls	__class__r%   r&   r1      s   



zBaseUnicodeTest.setUpClassc                    s   t    | jr| dd S )Nzcan't handle unicode str)r   setUpr2   skipTestselfr6   r%   r&   r8      s   

zBaseUnicodeTest.setUp)__name__
__module____qualname__r4   classmethodr1   r8   __classcell__r%   r%   r6   r&   r0      s
    r0   zASCII fsztoo much trouble on PYPY2c                   @   s   e Zd ZdZeZdd Zdd Zdd Zdd	 Z	d
d Z
eeo!eddd Zee ddd Zee dee de dd Zdd Zee dee deeddd ZdS )
TestFSAPIsz1Test FS APIs with a funky, valid, UTF8 path name.c                 C   s^   t | jtrdntd}t  td | jt|v W  d    S 1 s(w   Y  d S )N.ignore)	
isinstancer3   strr   warningscatch_warningssimplefilteroslistdir)r;   herer%   r%   r&   expect_exact_path_match   s
   

$z"TestFSAPIs.expect_exact_path_matchc                 C   sd   | j ddg}| |}t|j}| }| |t |  r0| 	t
j|t
j| j  d S d S Nz-czimport time; time.sleep(10))r3   r   psutilProcesspidexeassertIsInstancerE   rL   assertEqualrI   r$   normcase)r;   r)   subpprQ   r%   r%   r&   test_proc_exe   s   
zTestFSAPIs.test_proc_exec                 C   sX   | j ddg}| |}t|j }| |t |  r*| 	|t
j| j  d S d S rM   )r3   r   rN   rO   rP   namerR   rE   rL   rS   rI   r$   basename)r;   r)   rU   rX   r%   r%   r&   test_proc_name   s   
zTestFSAPIs.test_proc_namec                 C   s\   | j ddg}| |}t|j}| }|D ]}| |t q|  r,| 	|| d S d S rM   )
r3   r   rN   rO   rP   cmdlinerR   rE   rL   rS   )r;   r)   rU   rV   r[   partr%   r%   r&   test_proc_cmdline   s   
zTestFSAPIs.test_proc_cmdlinec                 C   s   | j d }| t| t| t| t }| }W d    n1 s&w   Y  | | t	 | 
 r?| || d S d S N2)r3   
addCleanupr   r   r   rN   rO   cwdrR   rE   rL   rS   )r;   dnamerV   ra   r%   r%   r&   test_proc_cwd   s   


zTestFSAPIs.test_proc_cwdzfails on PYPY + WINDOWSc                 C   s   t  }t| }t| jd t| }W d    n1 s!w   Y  ||  j}| |t	 t
r<|s<| dS |  rQ| tj|tj| j d S d S )Nrbzopen_files on BSD is broken)rN   rO   setZ
open_filesopenr3   popr$   rR   rE   r   r9   rL   rS   rI   rT   )r;   rV   startnewr$   r%   r%   r&   test_proc_open_files   s   
zTestFSAPIs.test_proc_open_filesz
POSIX onlyc                 C   s   | j | jd}zt|}W n ty   tr tdw t|  t	 
dd }| |jt | |j| W d    d S 1 sDw   Y  d S )Nr'   not supportedunixr   )r   r4   r   r,   r   unittestSkipTestr   rN   rO   connectionsrR   laddrrE   rS   )r;   rX   sockconnr%   r%   r&   test_proc_connections   s   

"z TestFSAPIs.test_proc_connectionszcan't list UNIX socketsc                 C   s   dd }| j | jd}zt|}W n ty    tr tdw t|! tj	dd}||}| 
|jt | |j| W d    d S 1 sIw   Y  d S )Nc                 S   s.   | D ]}t j|jtr|  S qtd)Nzconnection not found)rI   r$   rY   rp   
startswithr   
ValueError)consrr   r%   r%   r&   	find_sock  s
   z2TestFSAPIs.test_net_connections.<locals>.find_sockr'   rk   rl   )kind)r   r4   r   r,   r   rm   rn   r   rN   Znet_connectionsrR   rp   rE   rS   )r;   rw   rX   rq   rv   rr   r%   r%   r&   test_net_connections  s   

"zTestFSAPIs.test_net_connectionsc                 C   s,   | j d }| t| t| t| d S r^   )r3   r`   r   r   rN   
disk_usage)r;   rb   r%   r%   r&   test_disk_usage'  s   
zTestFSAPIs.test_disk_usagerk   z&ctypes does not support unicode on PY2zunstable on PYPYc                    s   t | jd4}dd   fddt  D }dd |D }|  || |D ]}| |t q)W d    d S 1 s=w   Y  d S )Nr'   c                 S   s   t jt j| S )N)rI   r$   realpathrT   )rV   r%   r%   r&   normpath5  s   z-TestFSAPIs.test_memory_maps.<locals>.normpathc                    s   g | ]} |j qS r%   )r$   .0xr}   r%   r&   
<listcomp>8  s    
z/TestFSAPIs.test_memory_maps.<locals>.<listcomp>c                 S   s   g | ]}t |v r|qS r%   r   r~   r%   r%   r&   r   <  s    )r   r4   rN   rO   Zmemory_mapsZassertInrR   rE   )r;   Z
funky_pathZlibpathsr$   r%   r   r&   test_memory_maps-  s   

"zTestFSAPIs.test_memory_mapsN)r<   r=   r>   __doc__r   r4   rL   rW   rZ   r]   rc   rm   skipIfr   r   rj   r   rs   r   r   ry   r{   r   r   r   r%   r%   r%   r&   rA      s*    




rA   zunreliable on CIc                   @   s   e Zd ZdZeZdd ZdS )TestFSAPIsWithInvalidPathz-Test FS APIs with a funky, invalid path name.c                 C   s   dS )NTr%   r:   r%   r%   r&   rL   H  s   z1TestFSAPIsWithInvalidPath.expect_exact_path_matchN)r<   r=   r>   r   r   r4   rL   r%   r%   r%   r&   r   B  s    r   c                   @   sB   e Zd ZdZer
endZee	 dee
oeddd ZdS )TestNonFSAPISz&Unicode tests for non fs-related APIs.   èrk   zsegfaults on PYPY + WINDOWSc                 C   st   t j }| j|d< | j|d}t|j}| }| D ]\}}| 	|t
 | 	|t
 q| |d | j d S )NZ	FUNNY_ARG)env)rI   environcopyr4   r   rN   rO   rP   itemsrR   rE   rS   )r;   r   r.   rV   kvr%   r%   r&   test_proc_environW  s   

zTestNonFSAPIS.test_proc_environN)r<   r=   r>   r   r   r   r4   rm   r   r   r   r   r   r%   r%   r%   r&   r   R  s    r   __main__)run_from_name)1r   rI   r*   r"   rm   rF   
contextlibr   rN   r   r   r   Zpsutil._compatr   r   r   r!   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r/   r0   r   rA   r   r   r<   Zpsutil.tests.runnerr   __file__r%   r%   r%   r&   <module>   sh   C
 


