diff --git a/psutil/_compat.py b/psutil/_compat.py index 18b2e85d4..9062ec977 100644 --- a/psutil/_compat.py +++ b/psutil/_compat.py @@ -17,6 +17,7 @@ long = int xrange = range unicode = str + basestring = str def u(s): return s @@ -27,6 +28,7 @@ def b(s): long = long xrange = xrange unicode = unicode + basestring = basestring def u(s): return unicode(s, "unicode_escape") diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 491526e1e..c09d180a6 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -32,6 +32,7 @@ from ._common import supports_ipv6 from ._common import usage_percent from ._compat import b +from ._compat import basestring from ._compat import long from ._compat import PY3 @@ -152,14 +153,19 @@ def get_procfs_path(): def readlink(path): """Wrapper around os.readlink().""" + assert isinstance(path, basestring), path path = os.readlink(path) - # readlink() might return paths containing null bytes causing - # problems when used with other fs-related functions (os.*, - # open(), ...), see: + # readlink() might return paths containing null bytes ('\x00') + # resulting in "TypeError: must be encoded string without NULL + # bytes, not str" errors when the string is passed to other + # fs-related functions (os.*, open(), ...). + # Apparently everything after '\x00' is garbage (we can have + # ' (deleted)', 'new' and possibly others), see: # https://github.com/giampaolo/psutil/issues/717 - path = path.replace('\x00', '') + path = path.split('\x00')[0] # Certain paths have ' (deleted)' appended. Usually this is - # bogus as the file actually exists. + # bogus as the file actually exists. Even if it doesn't we + # don't care. if path.endswith(' (deleted)') and not path_exists_strict(path): path = path[:-10] return path