
    Xi)                        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 Z# G d  d!e          Z$ej%        &                    d"#          ej%        '                    ed$%           G d& d'e$                                  Z(ej%        '                    ed(%           G d) d*e(                      Z) G 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                    d}t          |           }	 t          |           t          |           t          |g          }t	          j        ||dz              t          |dz              	 |t          |           t          |           dS # t          t          f$ r$ Y |t          |           t          |           dS w xY w# |t          |           t          |           w xY w)z`Return True if both the fs and the subprocess module can
    deal with a unicode file name.
    Nsuffix)cmdz-2TF)	r   r   r   r   shutilcopyfiler    UnicodeEncodeErrorOSError)r#   sproctestfns      q/var/www/development/aibuddy-work/election-extract/venv/lib/python3.11/site-packages/psutil/tests/test_unicode.pytry_unicoder,   h   s    Ev&&&FFf6(+++...FTM""" eF (    eF
 eFs$   AB C!C CC "C*c                   <     e Zd ZdZe fd            Z fdZ xZS )BaseUnicodeTestNc                    t                                                       d| _        d | _        | j        Mt          | j                  s	d| _        d S t          | j                  | _        t          | j                   d S d S )NFTr"   )super
setUpClass
skip_tests
funky_namefunky_suffixr,   r   r   )cls	__class__s    r+   r1   zBaseUnicodeTest.setUpClass   s    's/00 .!%!+33C!D!D!Dcn----- ('    c                 ~    t                                                       | j        rt          j        d          S d S )Nzcan't handle unicode str)r0   setUpr2   r   skip)selfr6   s    r+   r9   zBaseUnicodeTest.setUp   s9    ? 	;;9:::	; 	;r7   )__name__
__module____qualname__r4   classmethodr1   r9   __classcell__)r6   s   @r+   r.   r.      s`        L	. 	. 	. 	. [	.; ; ; ; ; ; ; ; ;r7   r.   serial)namezASCII fsreasonc                   `   e Zd ZdZeZd Zd Zd Zd Z	d Z
ej                            eoed          ej                            eped	          d
                         Zej                            e d          ej                            e d          d                         Zej                            e d          ej                            e d           e            d                                     Zd Zej                            e d          d             ZdS )
TestFSAPIsz1Test FS APIs with a funky, valid, UTF8 path name.c                     t          j                    5  t          j        d           | j        t	          j        d          v cd d d            S # 1 swxY w Y   d S )Nignore.)warningscatch_warningssimplefilterr3   oslistdirr;   s    r+   expect_exact_path_matchz"TestFSAPIs.expect_exact_path_match   s    $&& 	6 	6!(+++?bjoo5	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6s   /AAAc                    | j         ddg}|                     |          }t          j        |j                  }|                                }t          |t                    sJ |                                 rGt          j
                            |          t          j
                            | j                   k    sJ d S d S Nz-cz2import time; [time.sleep(0.1) for x in range(100)])r3   r   psutilProcesspidexe
isinstancestrrP   rM   pathnormcase)r;   r$   subpprV   s        r+   test_proc_exezTestFSAPIs.test_proc_exe   s    O@

 !!#&&N48$$eegg#s#####'')) 	N7##C((BG,<,<T_,M,MMMMM	N 	NMMr7   c                 H   | j         ddg}|                     |          }t          j        |j                                                  }t          |t                    sJ |                                 r*|t          j
                            | j                   k    sJ d S d S rR   )r3   r   rS   rT   rU   rB   rW   rX   rP   rM   rY   basename)r;   r$   r[   rB   s       r+   test_proc_namezTestFSAPIs.test_proc_name   s    O@

 !!#&&~dh'',,..$$$$$$'')) 	=27++DO<<<<<<	= 	=<<r7   c                    | j         ddg}|                     |          }t          j        |j                  }|                                }|D ]}t          |t                    sJ |                                 r||k    sJ d S d S rR   )	r3   r   rS   rT   rU   cmdlinerW   rX   rP   )r;   r$   r[   r\   rb   parts         r+   test_proc_cmdlinezTestFSAPIs.test_proc_cmdline   s    O@

 !!#&&N48$$))++ 	) 	)DdC(((((('')) 	"c>>>>	" 	"!>r7   c                    | j         dz   }|                     t          |           t          |           t	          |          5  t          j                    }|                                }d d d            n# 1 swxY w Y   t          |                                t                    sJ | 
                                r||k    sJ d S d S N2)r3   
addCleanupr   r   r   rS   rT   cwdrW   rX   rP   )r;   dnamer\   ri   s       r+   test_proc_cwdzTestFSAPIs.test_proc_cwd   s    #%U+++55\\ 	 	  A%%''C	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 !%%''3''''''')) 	 %<<<<	  	 <s   (A88A<?A<zfails on PYPY + WINDOWSrC   zbroken on NETBSD or OPENBSDc                 d   t          j                    }t          |                                          }t	          | j        d          5  t          |                                          }d d d            n# 1 swxY w Y   ||z
                                  j        }t          |t                    sJ t          r|st          j        d          S |                                 rGt          j                            |          t          j                            | j                  k    sJ d S d S )Nrbzopen_files on BSD is broken)rS   rT   set
open_filesopenr3   poprY   rW   rX   r   r   r:   rP   rM   rZ   )r;   r\   startnewrY   s        r+   test_proc_open_fileszTestFSAPIs.test_proc_open_files   sJ   
 NALLNN##$/4(( 	& 	&allnn%%C	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&e  ""'$$$$$$ 	>t 	>;<==='')) 	O7##D))RW-=-=do-N-NNNNN	O 	ONNs   
"A88A<?A<z
POSIX onlyzcan't list UNIX socketsc                    |                      | j                  }t          |          }t          |          5  t	          j                                        d          d         }t          |j        t                    sJ |j        s.t          r't          r t          j        d          cd d d            S |j        |k    sJ 	 d d d            d S # 1 swxY w Y   d S )Nr"   unixr   zunreliable on OSX)r   r4   r   r   rS   rT   net_connectionsrW   laddrrX   r   r   r   r:   )r;   rB   sockconns       r+   test_proc_net_connectionsz$TestFSAPIs.test_proc_net_connections   s5   
 d&788%%T]] 	& 	&>##33F;;A>Ddj#.....: 8% 8J 8{#677		& 	& 	& 	& 	& 	& 	& 	&
 :%%%%%	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&s   A1C8CCCc                 D   d }|                      | j                  }t          |          }t          |          5  t	          j        d          } ||          }t          |j        t                    sJ |j        |k    sJ 	 d d d            d S # 1 swxY w Y   d S )Nc                     | D ]B}t           j                            |j                                      t
                    r|c S Ct          d          )Nzconnection not found)rM   rY   r_   rx   
startswithr   
ValueError)consrz   s     r+   	find_sockz2TestFSAPIs.test_net_connections.<locals>.find_sock   sV        7##DJ//::=II  KKK 3444r7   r"   rv   )kind)	r   r4   r   r   rS   rw   rW   rx   rX   )r;   r   rB   ry   r   rz   s         r+   test_net_connectionszTestFSAPIs.test_net_connections   s    	5 	5 	5 d&788%%T]] 	& 	&)v666D9T??Ddj#.....:%%%%%		& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&s   A
BBBc                     | j         dz   }|                     t          |           t          |           t	          j        |           d S rf   )r3   rh   r   r   rS   
disk_usage)r;   rj   s     r+   test_disk_usagezTestFSAPIs.test_disk_usage  sG    #%U+++5%     r7   not supportedc                 <   t          | j                  5 }d fdt          j                                                    D             }d |D             } |          |v sJ |D ]}t          |t                    sJ 	 d d d            d S # 1 swxY w Y   d S )Nr"   c                 z    t           j                            t           j                            |                     S N)rM   rY   realpathrZ   )r\   s    r+   normpathz-TestFSAPIs.test_memory_maps.<locals>.normpath  s(    w''(8(8(;(;<<<r7   c                 0    g | ]} |j                   S  )rY   ).0xr   s     r+   
<listcomp>z/TestFSAPIs.test_memory_maps.<locals>.<listcomp>  s2       %&    r7   c                 $    g | ]}t           |v |S r   r   )r   r   s     r+   r   z/TestFSAPIs.test_memory_maps.<locals>.<listcomp>  s"    BBBa}/A/A/A/A/Ar7   )r   r4   rS   rT   memory_mapsrW   rX   )r;   
funky_pathlibpathsrY   r   s       @r+   test_memory_mapszTestFSAPIs.test_memory_maps  s!    (9::: 	-j= = =   *0.*:*:*F*F*H*H  H CB8BBBH8J''83333  - -!$,,,,,,-	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   A,BBBN)r<   r=   r>   __doc__r   r4   rP   r]   r`   rd   rk   r   markskipifr   r
   r   r   rt   r	   r   r{   r   r   r   r   r   r   r7   r+   rF   rF      s        <;!L6 6 6N N N
= 
= 
=" " "	  	  	  [(1JKK['"?   O O  LKO [E	,77[$$-F   & &  87& [E	,77[$$-F    & &   87
&! ! ! [O+ODD- - ED- - -r7   rF   zunreliable on CIc                       e Zd ZdZeZd ZdS )TestFSAPIsWithInvalidPathz-Test FS APIs with a funky, invalid path name.c                     t            S r   r   rO   s    r+   rP   z1TestFSAPIsWithInvalidPath.expect_exact_path_match(  s
    yr7   N)r<   r=   r>   r   r   r4   rP   r   r7   r+   r   r   "  s.        77)L    r7   r   c                       e Zd ZdZeZej                            e	 d          ej                            e
oed          d                         ZdS )TestNonFSAPISz&Unicode tests for non fs-related APIs.r   rC   zsegfaults on PYPY + WINDOWSc                    t           j                                        }| j        |d<   |                     |          }t          j        |j                  }|                                }|                                D ]3\  }}t          |t                    sJ t          |t                    sJ 4|d         | j        k    sJ d S )N	FUNNY_ARG)env)rM   environcopyr4   r   rS   rT   rU   itemsrW   rX   )r;   r   r)   r\   kvs         r+   test_proc_environzTestNonFSAPIS.test_proc_environ6  s    
 joo,K""s"++N59%%iikkIIKK 	& 	&DAqa%%%%%a%%%%%%;4#4444444r7   N)r<   r=   r>   r   r   r4   r   r   r   r   r   r
   r   r   r7   r+   r   r   1  sx        00!L[K@@[(1NOO5 5 PO A@5 5 5r7   r   )+r   rM   r%   rJ   
contextlibr   rS   r   r   r   r   r	   r
   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   xdist_groupr   rF   r   r   r   r7   r+   <module>r      s[  < <| 
			                                              ! ! ! ! ! ! # # # # # # $ $ $ $ $ $ ( ( ( ( ( ( 1 1 1 1 1 1 / / / / / /       & & & & & & ' ' ' ' ' ' ' ' ' ' ' ' ) ) ) ) ) )       , , , , , , & & & & & & # # # # # #       # # # # # # $ $ $ $ $ $ . . . . . . & & & & & & " " " " " "  6; ; ; ; ;n ; ; ;* h''HZ00E- E- E- E- E- E- E- 10 ('E-P J'9::    
   ;:5 5 5 5 5O 5 5 5 5 5r7   