diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2015-08-30 04:29:11 -0700 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2015-08-30 04:29:11 -0700 |
commit | 5176c50dc4b67de5d760636a70444ed21c807dc4 (patch) | |
tree | a66b5f5693a6ed2bc760bc9eebbe359debdc7c6c | |
parent | b9823dbb3071d902753e713b0c32d027e73a7946 (diff) | |
download | psutil-5176c50dc4b67de5d760636a70444ed21c807dc4.tar.gz |
always return encoded strings instead of unicode
-rw-r--r-- | HISTORY.rst | 18 | ||||
-rw-r--r-- | docs/index.rst | 13 | ||||
-rw-r--r-- | psutil/_pswindows.py | 37 | ||||
-rw-r--r-- | test/_windows.py | 26 |
4 files changed, 38 insertions, 56 deletions
diff --git a/HISTORY.rst b/HISTORY.rst index 9e7188b4..f283932a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,14 +7,16 @@ Bug tracker at https://github.com/giampaolo/psutil/issues - #648: CI test integration for OSX. (patch by Jeff Tang) - #663: net_if_addrs() now returns point-to-point addresses (for VPNs). -- #655: [Windows] str/uniocde unification. Different methods returning a string - now return unicode on both Python 2 and 3: - - net_if_stats - - net_io_counters - - users - - Process.username - - Process.name - - Process.cmdline +- #655: [Windows] different issues regarding unicode handling were fixed. On + Python 2 all APIs returning a string will now return an encoded version of it + by using sys.getfilesystemencoding() codec. The APIs involved are: + - psutil.net_if_stats + - psutil.net_if_addrs + - psutil.net_io_counters + - psutil.users + - psutil.Process.username + - psutil.Process.name + - psutil.Process.cmdline **Bug fixes** diff --git a/docs/index.rst b/docs/index.rst index f7dad748..4a2a5b94 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -681,26 +681,16 @@ Process class The process name. The return value is cached after first call. - *Changed in 3.2.0:* (Windows, Python 2) in case of non ASCII name the - returned type is unicode instead of str. - .. method:: exe() The process executable as an absolute path. On some systems this may also be an empty string. The return value is cached after first call. - *Changed in 3.2.0:* (Windows, Python 2) in case of non ASCII path the - returned type is unicode instead of str. - .. method:: cmdline() The command line this process has been called with. - *Changed in 3.2.0:* (Windows, Python 2) in case one or more parts of the - cmdline contains non ASCII characters the returned type is a list of - unicode strings. - .. method:: create_time() The process creation time as a floating point number expressed in seconds @@ -748,9 +738,6 @@ Process class The process current working directory as an absolute path. - *Changed in 3.2.0:* (Windows, Python 2) in case of non ASCII path the - returned type is unicode instead of str. - .. method:: username() The name of the user that owns the process. On UNIX this is calculated by diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 3c86d994..3e20d3be 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -234,13 +234,15 @@ def users(): return retlist -def py2_stringify(s): - if PY3: +def py2_strencode(s, encoding=sys.getfilesystemencoding()): + if PY3 or isinstance(s, str): return s else: try: - return str(s) + return s.encode(encoding) except UnicodeEncodeError: + # Filesystem codec failed, return the plain unicode + # string (this should never happen). return s @@ -297,9 +299,9 @@ class Process(object): try: # Note: this will fail with AD for most PIDs owned # by another user but it's faster. - return py2_stringify(os.path.basename(self.exe())) + return py2_strencode(os.path.basename(self.exe())) except AccessDenied: - return py2_stringify(cext.proc_name(self.pid)) + return py2_strencode(cext.proc_name(self.pid)) @wrap_exceptions def exe(self): @@ -311,7 +313,7 @@ class Process(object): # see https://github.com/giampaolo/psutil/issues/528 if self.pid in (0, 4): raise AccessDenied(self.pid, self._name) - return py2_stringify(_convert_raw_path(cext.proc_exe(self.pid))) + return py2_strencode(_convert_raw_path(cext.proc_exe(self.pid))) @wrap_exceptions def cmdline(self): @@ -319,16 +321,7 @@ class Process(object): if PY3: return ret else: - # On Python 2, if one or more bits of the cmdline is unicode - # we return a list of unicode strings. - new = [] - for x in ret: - x = py2_stringify(x) - if isinstance(x, unicode): - return ret - else: - new.append(x) - return new + return [py2_strencode(s) for s in ret] def ppid(self): try: @@ -453,13 +446,13 @@ class Process(object): # return a normalized pathname since the native C function appends # "\\" at the and of the path path = cext.proc_cwd(self.pid) - return py2_stringify(os.path.normpath(path)) + return py2_strencode(os.path.normpath(path)) @wrap_exceptions def open_files(self): if self.pid in (0, 4): return [] - retlist = [] + ret = set() # Filenames come in in native format like: # "\Device\HarddiskVolume1\Windows\systemew\file.txt" # Convert the first part in the corresponding drive letter @@ -467,10 +460,12 @@ class Process(object): raw_file_names = cext.proc_open_files(self.pid) for _file in raw_file_names: _file = _convert_raw_path(_file) - if isfile_strict(_file) and _file not in retlist: + if isfile_strict(_file): + if not PY3: + _file = py2_strencode(_file) ntuple = _common.popenfile(_file, -1) - retlist.append(ntuple) - return retlist + ret.add(ntuple) + return list(ret) @wrap_exceptions def connections(self, kind='inet'): diff --git a/test/_windows.py b/test/_windows.py index 70101726..0d2b2e15 100644 --- a/test/_windows.py +++ b/test/_windows.py @@ -476,32 +476,30 @@ class TestUnicode(unittest.TestCase): shutil.copyfile(sys.executable, self.uexe) subp = get_test_subprocess(cmd=[self.uexe]) p = psutil.Process(subp.pid) - self.assertIsInstance(p.name(), unicode) - self.assertEqual(os.path.basename(p.name()), u("psutil-è.exe")) + self.assertIsInstance(p.name(), str) + self.assertEqual(os.path.basename(p.name()), "psutil-è.exe") def test_proc_name(self): + from psutil._pswindows import py2_strencode shutil.copyfile(sys.executable, self.uexe) subp = get_test_subprocess(cmd=[self.uexe]) - self.assertIsInstance(psutil._psplatform.cext.proc_name(subp.pid), - unicode) - self.assertEqual(psutil._psplatform.cext.proc_name(subp.pid), - u("psutil-è.exe")) + self.assertEqual( + py2_strencode(psutil._psplatform.cext.proc_name(subp.pid)), + "psutil-è.exe") def test_proc_cmdline(self): shutil.copyfile(sys.executable, self.uexe) subp = get_test_subprocess(cmd=[self.uexe]) p = psutil.Process(subp.pid) - self.assertIsInstance(u("").join(p.cmdline()), unicode) - uexe = self.uexe if PY3 else \ - unicode(self.uexe, sys.getfilesystemencoding()) - self.assertEqual(p.cmdline(), [uexe]) + self.assertIsInstance("".join(p.cmdline()), str) + self.assertEqual(p.cmdline(), [self.uexe]) def test_proc_cwd(self): - tdir = tempfile.mkdtemp(prefix=u("psutil-è-")) + tdir = tempfile.mkdtemp(prefix="psutil-è-") self.addCleanup(safe_rmdir, tdir) with chdir(tdir): p = psutil.Process() - self.assertIsInstance(p.cwd(), unicode) + self.assertIsInstance(p.cwd(), str) self.assertEqual(p.cwd(), tdir) def test_proc_open_files(self): @@ -510,8 +508,8 @@ class TestUnicode(unittest.TestCase): with open(self.uexe, 'w'): new = set(p.open_files()) path = (new - start).pop().path - self.assertIsInstance(path, unicode) - self.assertEqual(path, self.uexe) + self.assertIsInstance(path, str) + self.assertEqual(path.lower(), self.uexe.lower()) def main(): |