o
    `qi)                     @   s  d 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  Z#G d!d" d"eZ$ej%j&d#d$ej%j'ed%d&G d'd( d(e$Z(ej%j'ed)d&G d*d+ d+e(Z)G d,d- d-e$Z*dS ).aY  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:
    * sys.getfilesystemencodeerrors() or "surrogatescape" on POSIX and
      "replace" on Windows.

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.cwd()
* Process.environ()
* Process.exe()
* Process.memory_maps()
* Process.name()
* Process.net_connections('unix')
* 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MACOS)NETBSD)OPENBSD)POSIX)WINDOWS)ASCII_FS)
CI_TESTING)HAS_ENVIRON)HAS_MEMORY_MAPS)HAS_NET_CONNECTIONS_UNIX)INVALID_UNICODE_SUFFIX)PYPYTESTFN_PREFIX)UNICODE_SUFFIX)PsutilTestCase)bind_unix_socket)chdir)copyload_shared_lib)create_py_exe)
get_testfn)pytest)
safe_mkdir)safe_rmpath)skip_on_access_denied)spawn_subproc)	terminatec              	   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OSErrorr   )r!   sprocZtestfn r(   `/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/psutil/tests/test_unicode.pytry_unicodeh   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    )super
setUpClass
skip_tests
funky_namefunky_suffixr*   r   r   )cls	__class__r(   r)   r-      s   



zBaseUnicodeTest.setUpClassc                    s   t    | jrtdS d S )Nzcan't handle unicode str)r,   setUpr.   r   skipselfr2   r(   r)   r4      s   

zBaseUnicodeTest.setUp)__name__
__module____qualname__r0   classmethodr-   r4   __classcell__r(   r(   r2   r)   r+      s
    r+   serial)namezASCII fsreasonc                   @   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jjeo"eddejjep+edddd Zejje ddejje dddd Zejje ddejje dde dd Zdd Zejje dddd ZdS )
TestFSAPIsz1Test FS APIs with a funky, valid, UTF8 path name.c                 C   sF   t   t d | jtdv W  d    S 1 sw   Y  d S )Nignore.)warningscatch_warningssimplefilterr/   oslistdirr6   r(   r(   r)   expect_exact_path_match   s   

$z"TestFSAPIs.expect_exact_path_matchc                 C   sf   | j ddg}| |}t|j}| }t|tsJ |  r/t	j
|t	j
| j ks1J d S d S Nz-cz2import time; [time.sleep(0.1) for x in range(100)])r/   r   psutilProcesspidexe
isinstancestrrI   rG   pathnormcase)r7   r"   subpprN   r(   r(   r)   test_proc_exe   s   
zTestFSAPIs.test_proc_exec                 C   sZ   | j ddg}| |}t|j }t|tsJ |  r)|t	j
| j ks+J d S d S rJ   )r/   r   rK   rL   rM   r>   rO   rP   rI   rG   rQ   basename)r7   r"   rS   r>   r(   r(   r)   test_proc_name   s   
zTestFSAPIs.test_proc_namec                 C   s^   | j ddg}| |}t|j}| }|D ]	}t|ts J q|  r+||ks-J d S d S rJ   )	r/   r   rK   rL   rM   cmdlinerO   rP   rI   )r7   r"   rS   rT   rX   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| t	s4J | 
 r>||ks@J d S d S N2)r/   
addCleanupr   r   r   rK   rL   cwdrO   rP   rI   )r7   dnamerT   r^   r(   r(   r)   test_proc_cwd   s   


zTestFSAPIs.test_proc_cwdzfails on PYPY + WINDOWSr?   zbroken on NETBSD or OPENBSDc                 C   s   t  }t| }t| jd t| }W d    n1 s!w   Y  ||  j}t|t	s4J t
r=|s=tdS |  rPtj|tj| jksRJ d S d S )Nrbzopen_files on BSD is broken)rK   rL   setZ
open_filesopenr/   poprQ   rO   rP   r   r   r5   rI   rG   rR   )r7   rT   startnewrQ   r(   r(   r)   test_proc_open_files   s   
zTestFSAPIs.test_proc_open_filesz
POSIX onlyzcan't list UNIX socketsc                 C   s   | j | jd}t|}t|4 t dd }t|jt	s!J |js4t
r4tr4tdW  d    S |j|ks;J W d    d S 1 sFw   Y  d S )Nr    unixr   zunreliable on OSX)r   r0   r   r   rK   rL   net_connectionsrO   laddrrP   r   r   r   r5   )r7   r>   sockconnr(   r(   r)   test_proc_net_connections   s   
"z$TestFSAPIs.test_proc_net_connectionsc                 C   s~   dd }| j | jd}t|}t|" tjdd}||}t|jts&J |j|ks-J W d    d S 1 s8w   Y  d S )Nc                 S   s.   | D ]}t j|jtr|  S qtd)Nzconnection not found)rG   rQ   rV   rj   
startswithr   
ValueError)consrl   r(   r(   r)   	find_sock   s
   z2TestFSAPIs.test_net_connections.<locals>.find_sockr    rh   )kind)	r   r0   r   r   rK   ri   rO   rj   rP   )r7   rq   r>   rk   rp   rl   r(   r(   r)   test_net_connections   s   
"zTestFSAPIs.test_net_connectionsc                 C   s,   | j d }| t| t| t| d S r[   )r/   r]   r   r   rK   
disk_usage)r7   r_   r(   r(   r)   test_disk_usage  s   
zTestFSAPIs.test_disk_usagenot supportedc                    s   t | jd5}dd   fddt  D }dd |D } ||v s'J |D ]	}t|ts2J q)W d    d S 1 s>w   Y  d S )Nr    c                 S   s   t jt j| S N)rG   rQ   realpathrR   )rT   r(   r(   r)   normpath  s   z-TestFSAPIs.test_memory_maps.<locals>.normpathc                    s   g | ]} |j qS r(   )rQ   .0xry   r(   r)   
<listcomp>  s    
z/TestFSAPIs.test_memory_maps.<locals>.<listcomp>c                 S   s   g | ]}t |v r|qS r(   r   rz   r(   r(   r)   r~     s    )r   r0   rK   rL   Zmemory_mapsrO   rP   )r7   Z
funky_pathZlibpathsrQ   r(   r}   r)   test_memory_maps  s   

"zTestFSAPIs.test_memory_mapsN)r8   r9   r:   __doc__r   r0   rI   rU   rW   rZ   r`   r   markskipifr   r	   r   r   rg   r   r   rm   r   rs   ru   r   r   r(   r(   r(   r)   rA      s6    
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   t  S rw   r   r6   r(   r(   r)   rI   (  s   z1TestFSAPIsWithInvalidPath.expect_exact_path_matchN)r8   r9   r:   r   r   r0   rI   r(   r(   r(   r)   r   "  s    r   c                   @   sB   e Zd ZdZeZejje	 ddejje
oedddd ZdS )TestNonFSAPISz&Unicode tests for non fs-related APIs.rv   r?   zsegfaults on PYPY + WINDOWSc                 C   sx   t j }| j|d< | j|d}t|j}| }| D ]\}}t	|t
s)J t	|t
s0J q|d | jks:J d S )NZ	FUNNY_ARG)env)rG   environcopyr0   r   rK   rL   rM   itemsrO   rP   )r7   r   r'   rT   kvr(   r(   r)   test_proc_environ6  s   

zTestNonFSAPIS.test_proc_environN)r8   r9   r:   r   r   r0   r   r   r   r   r   r	   r   r(   r(   r(   r)   r   1  s    r   )+r   rG   r#   rD   
contextlibr   rK   r   r   r   r   r   r	   Zpsutil.testsr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r*   r+   r   Zxdist_groupr   rA   r   r   r(   r(   r(   r)   <module>   sT   > 	