
    :Qg;1                        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$ erd Z!d  Z% G d! d"e      Z&ejN                  jQ                  d#$      ejN                  jS                  ed%&      ejN                  jS                  exr e d'&       G d( d)e&                           Z*ejN                  jS                  ed*&       G d+ d,e*             Z+ G d- d.e&      Z,y)/a>	  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)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     V/var/www/html/answerous/venv/lib/python3.12/site-packages/psutil/tests/test_unicode.pyr   r   q   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_unicoder2      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_suffixr2   r   r   )cls	__class__s    r'   r6   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   setUpr7   r   skip)selfr;   s    r'   r>   zBaseUnicodeTest.setUp   s*    ??++899 r<   )__name__
__module____qualname__r9   classmethodr6   r>   __classcell__)r;   s   @r'   r4   r4      s$    L	. 	.: :r<   r4   serial)namezASCII fsreasonztoo much trouble on PYPY2c                   6   e Zd ZdZeZd Zd Zd Z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)
isinstancer8   strwarningscatch_warningssimplefilteroslistdir)r@   heres     r'   expect_exact_path_matchz"TestFSAPIs.expect_exact_path_match   s\     !#6sD$$& 	7!!(+??bjj&66	7 	7 	7s   6A33A<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)])r8   r   psutilProcesspidexerO   rP   rW   rT   r%   normcase)r@   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 rY   )r8   r   rZ   r[   r\   rG   rO   rP   rW   rT   r%   basename)r@   r+   r_   rG   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 rY   )	r8   r   rZ   r[   r\   cmdlinerO   rP   rW   )r@   r+   r_   r`   rf   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)r8   
addCleanupr   r   r   rZ   r[   cwdrO   rP   rW   )r@   dnamer`   rm   s       r'   test_proc_cwdzTestFSAPIs.test_proc_cwd   s    #%U+55\ 	 A%%'C	 !%%'3''''')%<< *		 	s   %B""B+zfails on PYPY + WINDOWSrH   c                 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)rZ   r[   set
open_filesopenr8   popr%   rO   rP   r   r   r?   rW   rT   r^   )r@   r`   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   r9   r   r.   r   r   r?   r   rZ   r[   net_connectionsrO   laddrrP   )r@   rG   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)rT   r%   rc   r}   
startswithr   
ValueError)consr   s     r'   	find_sockz2TestFSAPIs.test_net_connections.<locals>.find_sock  sE      77##DJJ/::=IK  344r<   r)   rz   r{   )kind)r   r9   r   r.   r   r   r?   r   rZ   r|   rO   r}   rP   )r@   r   rG   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 rj   )r8   rl   r   r   rZ   
disk_usage)r@   rn   s     r'   test_disk_usagezTestFSAPIs.test_disk_usage/  s4    #%U+5% r<   rz   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)rT   r%   realpathr^   )r`   s    r'   normpathz-TestFSAPIs.test_memory_maps.<locals>.normpath?  s&    ww''(8(8(;<<r<   )	r   r9   rZ   r[   memory_mapsr%   r   rO   rP   )r@   
funky_pathr   xlibpathsr%   s         r'   test_memory_mapszTestFSAPIs.test_memory_maps5  s     !(9(9: 	-j= +1..*:*F*F*H%& H  $,Ba}/ABHBJ'8333  -!$,,,-	- 	-
 C	- 	-s4   (B+B!B+B&,B&0#B+B+!
B++B4N)rA   rB   rC   __doc__r   r9   rW   ra   rd   rh   ro   r   markskipifr   r   rx   r   r   r   r   r   r   r   r   r    r<   r'   rK   rK      sQ    <!L7N
="	  [[(1JKO LO [[E	,7& 8& [[E	,7[[$$-F   &  8
&*! [[O+OD[[@   [[%78- 9 E
-r<   rK   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   )r@   s    r'   rW   z1TestFSAPIsWithInvalidPath.expect_exact_path_matchR  s    r<   N)rA   rB   rC   r   r   r9   rW   r   r<   r'   r   r   L  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.   èrz   rH   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)rT   environcopyr9   r   rZ   r[   r\   itemsrO   rP   )r@   r   r0   r`   kvs         r'   test_proc_environzTestNonFSAPIS.test_proc_environa  s     jjoo,,K###,NN599%iikIIK 	&DAqa%%%a%%%	& ;4#4#4444r<   N)rA   rB   rC   r   r   r   r9   r   r   r   r   r   r   r   r   r<   r'   r   r   \  sZ    0%(>dL[[K@[[(1NO5 P A5r<   r   )-r   rT   r,   r#   rQ   
contextlibr   rZ   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   r2   r4   r   xdist_groupr   rK   r   r   r   r<   r'   <module>r      s:  AF 
            ! ! # $ ( 1 /  & ' ' )  , & #  # $ . ' " "&6:n :* h'HZ0D$W-HIR- R- J 1 (R-j J'9:
  ;5O 5r<   