
    g1                        d 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rd  Z"d! Z& G d" d#e      Z'e jP                  jS                  d$%      e jP                  jU                  ed&'      e jP                  jU                  exr e d('       G d) d*e'                           Z+e jP                  jU                  ed+'       G d, d-e+             Z, G d. d/e'      Z-y)0a>	  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.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)POSIX)WINDOWS)PY3)super)APPVEYOR)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_testproc)	terminatec                 f    ddl m} 	  ||       S # t        $ r t        j                          Y y w xY w)Nr   r   )psutil.testsr   WindowsError	traceback	print_exc)pathrms     N/var/www/openai/venv/lib/python3.12/site-packages/psutil/tests/test_unicode.pyr   r   r   s0     	3	"d8O 	"!	"s    00c                 |   d}t        |       }	 t        |       t        |       t        |g      }t	        j
                  ||dz          t        |dz          	 |t        |       t        |       y# t        t        f$ r Y |t        |       t        |       y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IOError)r+   sproctestfns      r(   try_unicoder3      s     Ev&FFfF8,.FTM" eF (  eF
 eFs$   A
A4 4BB! BB! !B;c                   6     e Zd ZdZe fd       Z fdZ xZS )BaseUnicodeTestNc                    t               j                          d| _        d | _        | j                  Nt        | j                        sd| _        y t        | j                        | _        t        | j                         y y )NFTr*   )r	   
setUpClass
skip_tests
funky_namefunky_suffixr3   r   r   )cls	__class__s    r(   r7   zBaseUnicodeTest.setUpClass   sc    's//0!%!+33C3C!Dcnn- (    c                 x    t               j                          | j                  rt        j                  d      y )Nzcan't handle unicode str)r	   setUpr8   r   skip)selfr<   s    r(   r?   zBaseUnicodeTest.setUp   s*    ??++899 r=   )__name__
__module____qualname__r:   classmethodr7   r?   __classcell__)r<   s   @r(   r5   r5      s$    L	. 	.: :r=   r5   serial)namezASCII fsreasonztoo much trouble on PYPY2c                      e Zd ZdZeZd Zej                  j                  e
xr e d      d        Zd Zej                  j                  e
xr e d      d        Zd Zej                  j                  exr ed	      d
        Zej                  j                  e d      d        Zej                  j                  e d      ej                  j                  e d       e       d                      Zd Zej                  j                  e d      ej                  j                  e d      ej                  j                  ed      d                      Zy)
TestFSAPIsz1Test FS APIs with a funky, valid, UTF8 path name.c                     t        | j                  t              rdnd}t        j                         5  t        j
                  d       | j                  t        j                  |      v cd d d        S # 1 sw Y   y xY w)N.ignore)
isinstancer9   strwarningscatch_warningssimplefilteroslistdir)rA   heres     r(   expect_exact_path_matchz"TestFSAPIs.expect_exact_path_match   sS     !#6sD$$&!!(+??bjj&66 '&&s   6A33A<zbroken MACOS + PY2rI   c                 ~   | j                   ddg}| j                  |      }t        j                  |j                        }|j                         }t        |t              sJ | j                         rLt        j                  j                  |      t        j                  j                  | j                         k(  sJ y y Nz-cz2import time; [time.sleep(0.1) for x in range(100)])r9   r   psutilProcesspidexerP   rQ   rX   rU   r&   normcase)rA   r,   subppr^   s        r(   test_proc_exezTestFSAPIs.test_proc_exe   s     OO@

 ""3'NN488$eeg#s###'')77##C(BGG,<,<T__,MMMM *r=   c                 @   | j                   ddg}| j                  |      }t        j                  |j                        j                         }t        |t              sJ | j                         r/|t        j                  j                  | j                         k(  sJ y y rZ   )r9   r   r[   r\   r]   rH   rP   rQ   rX   rU   r&   basename)rA   r,   r`   rH   s       r(   test_proc_namezTestFSAPIs.test_proc_name   s    OO@

 ""3'~~dhh',,.$$$$'')277++DOO<<<< *r=   c                    | j                   ddg}| j                  |      }t        j                  |j                        }|j                         }|D ]  }t        |t              rJ  | j                         r||k(  sJ y y rZ   )	r9   r   r[   r\   r]   cmdlinerP   rQ   rX   )rA   r,   r`   ra   rg   parts         r(   test_proc_cmdlinezTestFSAPIs.test_proc_cmdline   s~     OO@

 ""3'NN488$))+DdC((( '')c>!> *r=   c                 \   | j                   dz   }| j                  t        |       t        |       t	        |      5  t        j                         }|j                         }d d d        t        j                         t              sJ | j                         r|k(  sJ y y # 1 sw Y   BxY wN2)r9   
addCleanupr   r   r   r[   r\   cwdrP   rQ   rX   )rA   dnamera   rn   s       r(   test_proc_cwdzTestFSAPIs.test_proc_cwd   s    #%U+55\ A%%'C  !%%'3''''')%<< *	 \s   %B""B+zfails on PYPY + WINDOWSc                 6   t        j                         }t        |j                               }t	        | j
                  d      5  t        |j                               }d d d        |z
  j                         j                  }t        |t              sJ t        r|st        j                  d      | j                         rLt        j                  j                  |      t        j                  j                  | j
                        k(  sJ y y # 1 sw Y   xY w)Nrbzopen_files on BSD is broken)r[   r\   set
open_filesopenr9   popr&   rP   rQ   r   r   r@   rX   rU   r_   )rA   ra   startnewr&   s        r(   test_proc_open_fileszTestFSAPIs.test_proc_open_files   s    NNALLN#$//4(alln%C )e  "''$$$$t++;<<'')77##D)RWW-=-=doo-NNNN * )(s   DDz
POSIX onlyc                    | j                  | j                        }	 t        |      }t        |      5  t        j                         j                  d      d   }t        |j                  t              sJ |j                  |k(  sJ 	 d d d        y # t        $ r t        r t        j                  d      w xY w# 1 sw Y   y xY w)Nr*   not supportedunixr   )r   r:   r   r/   r   r   r@   r   r[   r\   net_connectionsrP   laddrrQ   )rA   rH   sockconns       r(   test_proc_net_connectionsz$TestFSAPIs.test_proc_net_connections	  s    d&7&78	3#D)D T]>>#33F;A>Ddjj#...::%%% ] " 	3kk/22		3
 ]s   B AB;&B8;Czcan't list UNIX socketsc                    d }| j                  | j                        }	 t        |      }t        |      5  t        j                  d      } ||      }t        |j                  t              sJ |j                  |k(  sJ 	 d d d        y # t        $ r t        r t        j                  d      w xY w# 1 sw Y   y xY w)Nc                     | D ]B  }t         j                  j                  |j                        j	                  t
              s@|c S  t        d      )Nzconnection not found)rU   r&   rd   r~   
startswithr   
ValueError)consr   s     r(   	find_sockz2TestFSAPIs.test_net_connections.<locals>.find_sock  s@    77##DJJ/::=IK  344r=   r*   r{   r|   )kind)r   r:   r   r/   r   r   r@   r   r[   r}   rP   r~   rQ   )rA   r   rH   r   r   r   s         r(   test_net_connectionszTestFSAPIs.test_net_connections  s    	5 d&7&78	3#D)D T]))v6DT?Ddjj#...::%%%	 ] " 	3kk/22		3
 ]s   B AB6&B36B?c                     | j                   dz   }| j                  t        |       t        |       t	        j
                  |       y rk   )r9   rm   r   r   r[   
disk_usage)rA   ro   s     r(   test_disk_usagezTestFSAPIs.test_disk_usage2  s4    #%U+5% r=   r{   z&ctypes does not support unicode on PY2zunstable on PYPYc                 n   t        | j                        5 }d }t        j                         j	                         D cg c]  } ||j
                         }}|D cg c]  }t        |v s| }} ||      |v sJ |D ]  }t        |t              rJ  	 d d d        y c c}w c c}w # 1 sw Y   y xY w)Nr*   c                 z    t         j                  j                  t         j                  j                  |             S )N)rU   r&   realpathr_   )ra   s    r(   normpathz-TestFSAPIs.test_memory_maps.<locals>.normpathB  s&    ww''(8(8(;<<r=   )	r   r:   r[   r\   memory_mapsr&   r   rP   rQ   )rA   
funky_pathr   xlibpathsr&   s         r(   test_memory_mapszTestFSAPIs.test_memory_maps8  s     !(9(9:j= +1..*:*F*F*H*HQ *H   $,B8a}/A8HBJ'8333 !$,,, ! ;:
 C ;:s4   (B+B!B+B&,B&0#B+B+!
B++B4N)rB   rC   rD   __doc__r   r:   rX   r   markskipifr   r   rb   re   ri   rp   r   r   ry   r   r   r   r   r   r   r   r    r=   r(   rL   rL      s    <!L7 [[)c'2FGN HN
= [[)c'2FG" H"	  [[(1JKO LO [[E	,7& 8& [[E	,7[[$$-F   &  8
&*! [[O+OD[[@   [[%78- 9 E
-r=   rL   zunreliable on CIc                       e Zd ZdZeZd Zy)TestFSAPIsWithInvalidPathz-Test FS APIs with a funky, invalid path name.c                      y)NTr   )rA   s    r(   rX   z1TestFSAPIsWithInvalidPath.expect_exact_path_matchU  s    r=   N)rB   rC   rD   r   r   r:   rX   r   r=   r(   r   r   O  s    7)Lr=   r   c                       e Zd ZdZerendZej                  j                  e
 d      ej                  j                  exr ed      d               Zy)TestNonFSAPISz&Unicode tests for non fs-related APIs.   èr{   rI   zsegfaults on PYPY + WINDOWSc                    t         j                  j                         }| j                  |d<   | j	                  |      }t        j                  |j                        }|j                         }|j                         D ])  \  }}t        |t              sJ t        |t              r)J  |d   | j                  k(  sJ y )N	FUNNY_ARG)env)rU   environcopyr:   r   r[   r\   r]   itemsrP   rQ   )rA   r   r1   ra   kvs         r(   test_proc_environzTestNonFSAPIS.test_proc_environd  s     jjoo,,K###,NN599%iikIIKDAqa%%%a%%%   ;4#4#4444r=   N)rB   rC   rD   r   r   r   r:   r   r   r   r   r   r   r   r   r=   r(   r   r   _  sZ    0%(>dL[[K@[[(1NO5 P A5r=   r   ).r   rU   r-   r$   rR   
contextlibr   r[   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   r5   r   xdist_groupr   rL   r   r   r   r=   r(   <module>r      s=  AF 
             ! ! # $ ( 1 /  & ' ' )  , & #  # $ . ' " "&6:n :* h'HZ0D$W-HIT- T- J 1 (T-n J'9:
  ;5O 5r=   