U =_0@s<dZddlZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ddlm Z ddl m Z dd l mZdd lmZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm!Z!ddlm"Z"ddlm#Z#ddlm$Z$ddlm%Z%dd lm&Z&ddlZerd!d"Zd#d$Z'Gd%d&d&eZ(e e&)ed'e&)eoe d(Gd)d*d*e(Z*e&)ed+Gd,d-d-e*Z+Gd.d/d/e(Z,e-d0kr8dd1l.m/Z/e/e0dS)2a: 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)bind_unix_socket)chdir) CI_TESTING)copyload_shared_lib) create_exe) get_testfn)HAS_CONNECTIONS_UNIX) HAS_ENVIRON)HAS_MEMORY_MAPS)INVALID_UNICODE_SUFFIX)PsutilTestCase)PYPY) safe_mkdir safe_rmpath) serialrun)skip_on_access_denied)spawn_testproc) terminate TESTFN_PREFIX)UNICODE_SUFFIX)unittestcCs8ddlm}z ||WStk r2tYnXdS)Nrr) psutil.testsrZ WindowsError traceback print_exc)pathZrmr&L/opt/alt/python38/lib64/python3.8/site-packages/psutil/tests/test_unicode.pyrss  rc Csd}t|d}zhz.find_sockr(rirj)Zkind)rr2r r-rr!rkrrLZnet_connectionsrrPrlrCrQ)r4rsrVrmrrrnr&r&r'test_net_connectionss   zTestFSAPIs.test_net_connectionscCs,|jd}|t|t|t|dSr\)r:r^rrrLZ disk_usage)r4r`r&r&r'test_disk_usage"s  zTestFSAPIs.test_disk_usageriz&ctypes does not support unicode on PY2zunstable on PYPYc srt|jd\}ddfddtD}dd|D}||||D]}||tqRW5QRXdS)Nr(cSstjtj|Sr>)rGr%realpathrR)rTr&r&r'normpath/sz-TestFSAPIs.test_memory_maps..normpathcsg|]}|jqSr&)r%.0xrwr&r' 1sz/TestFSAPIs.test_memory_maps..cSsg|]}t|kr|qSr&rrxr&r&r'r|4s)rr2rLrMZ memory_mapsZassertInrPrC)r4Z funky_pathZlibpathsr%r&r{r'test_memory_maps(s  zTestFSAPIs.test_memory_mapsN)r6r7r8__doc__r r2 classmethodr=r?rJrUrXr[rar!skipIfrrrhrrorrrtrurrr}r&r&r&r'r9s0              r9zunreliable on CIc@s eZdZdZeZeddZdS)TestFSAPIsWithInvalidPathz-Test FS APIs with a funky, invalid path name.cCsdS)NTr&r;r&r&r'rJ?sz1TestFSAPIsWithInvalidPath.expect_exact_path_matchN)r6r7r8r~rr2rrJr&r&r&r'r:src@sBeZdZdZerendZee dee o.e dddZ dS) TestNonFSAPISz&Unicode tests for non fs-related APIs.èrizsegfaults on PYPY + WINDOWScCsttj}|j|d<|j|d}t|j}|}|D] \}}| |t | |t q<| |d|jdS)NZ FUNNY_ARG)env) rGenvironcopyr2rrLrMrNitemsrPrCrQ)r4rr/rTkvr&r&r'test_proc_environNs     zTestNonFSAPIS.test_proc_environN) r6r7r8r~rr r2r!rrrrrr&r&r&r'rJs   r__main__) run_from_name)1r~rGr,r#rD contextlibrrLrrrrZpsutil._compatrrr"r r r r r rrrrrrrrrrrrrrrrr r!r0r1rr9rrr6Zpsutil.tests.runnerr__file__r&r&r&r'sdD