o
    i0                     @   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)OPENBSD)POSIX)WINDOWS)PY3)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_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   WindowsError	traceback	print_exc)pathrm r'   T/var/www/edux/Edux_v2/venv/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*   sproctestfnr'   r'   r(   try_unicode   s*   

r3   c                   @   s   e Zd ZdZdd ZdS )BaseUnicodeTestNc                 C   s&   | j d urt| j s| dd S d S )Nzcan't handle unicode str)funky_suffixr3   skipTest)selfr'   r'   r(   setUp   s
   


zBaseUnicodeTest.setUp)__name__
__module____qualname__r5   r8   r'   r'   r'   r(   r4      s    r4   zASCII fsztoo much trouble on PYPY2c                   @   s   e Zd ZdZeZedd Zedd 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d| _t| j d S )Nr)   )r   r5   
funky_namer   clsr'   r'   r(   
setUpClass   s   zTestFSAPIs.setUpClassc                 C   s   t | j d S N)r   r=   r>   r'   r'   r(   tearDownClass   s   zTestFSAPIs.tearDownClassc                 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)	
isinstancer=   strr   warningscatch_warningssimplefilteroslistdir)r7   herer'   r'   r(   expect_exact_path_match   s
   

$z"TestFSAPIs.expect_exact_path_matchc                 C   s^   | j | jgd}t|j}| }| |t |  r-| 	t
j|t
j| j d S d S Nr+   )r   r=   psutilProcesspidexeassertIsInstancerF   rM   assertEqualrJ   r%   normcase)r7   subpprR   r'   r'   r(   test_proc_exe   s   zTestFSAPIs.test_proc_exec                 C   sR   | j | jgd}t|j }| |t |  r'| 	|t
j| j d S d S rN   )r   r=   rO   rP   rQ   namerS   rF   rM   rT   rJ   r%   basename)r7   rV   rY   r'   r'   r(   test_proc_name   s   zTestFSAPIs.test_proc_namec                 C   sZ   | j | jgd}t|j}| }|D ]}| |t q|  r+| 	|| jg d S d S rN   )
r   r=   rO   rP   rQ   cmdlinerS   rF   rM   rT   )r7   rV   rW   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)r=   
addCleanupr   r   r   rO   rP   cwdrS   rF   rM   rT   )r7   dnamerW   rb   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)rO   rP   set
open_filesopenr=   popr%   rS   rF   r   r6   rM   rT   rJ   rU   )r7   rW   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 tsC| |j| W d    d S W d    d S 1 sNw   Y  d S )Nr)   not supportedunixr   )r   r5   r   r/   r   unittestSkipTestr   rO   rP   connectionsrS   laddrrF   r   rT   )r7   rY   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}t
sH||}| |jt | |j| W d    d S W d    d S 1 sSw   Y  d S )Nc                 S   s.   | D ]}t j|jtr|  S qtd)Nzconnection not found)rJ   r%   rZ   rr   
startswithr   
ValueError)consrt   r'   r'   r(   	find_sock  s
   z2TestFSAPIs.test_net_connections.<locals>.find_sockr)   rm   rn   )kind)r   r5   r   r/   r   ro   rp   r   rO   net_connectionsr   rS   rr   rF   rT   )r7   ry   rY   rs   rx   rt   r'   r'   r(   test_net_connections  s$   

"zTestFSAPIs.test_net_connectionsc                 C   s,   | j d }| t| t| t| d S r_   )r=   ra   r   r   rO   
disk_usage)r7   rc   r'   r'   r(   test_disk_usage"  s   
zTestFSAPIs.test_disk_usagerm   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 rA   )rJ   r%   realpathrU   )rW   r'   r'   r(   normpath/  s   z-TestFSAPIs.test_memory_maps.<locals>.normpathc                    s   g | ]} |j qS r'   )r%   .0xr   r'   r(   
<listcomp>1  s    z/TestFSAPIs.test_memory_maps.<locals>.<listcomp>c                 S   s   g | ]}t |v r|qS r'   r   r   r'   r'   r(   r   4  s    )r   r5   rO   rP   memory_mapsassertInrS   rF   )r7   
funky_pathlibpathsr%   r'   r   r(   test_memory_maps(  s   

"zTestFSAPIs.test_memory_mapsN)r9   r:   r;   __doc__r   r5   classmethodr@   rB   rM   rX   r[   r^   rd   ro   skipIfr   r   rl   r   ru   r   r   r|   r~   r   r   r   r'   r'   r'   r(   r<      s2    


		


r<   zunreliable on CIc                   @   s    e Zd ZdZeZe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(   rM   ?  s   z1TestFSAPIsWithInvalidPath.expect_exact_path_matchN)r9   r:   r;   r   r   r5   r   rM   r'   r'   r'   r(   r   :  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.   èrm   zsegfaults on PYPY + WINDOWSc                 C   st   t j }| j|d< | j|d}t|j}| }| D ]\}}| 	|t
 | 	|t
 q| |d | j d S )N	FUNNY_ARG)env)rJ   environcopyr5   r   rO   rP   rQ   itemsrS   rF   rT   )r7   r   r1   rW   kvr'   r'   r(   test_proc_environN  s   

zTestNonFSAPIS.test_proc_environN)r9   r:   r;   r   r   r   r5   ro   r   r   r   r   r   r'   r'   r'   r(   r   J  s    r   __main__)run_from_name)1r   rJ   r-   r#   ro   rG   
contextlibr   rO   r   r   r   r   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    r3   r4   r   r<   r   r   r9   psutil.tests.runnerr   __file__r'   r'   r'   r(   <module>   sh   D	
 

