diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2019-04-05 07:38:57 -0700 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2019-04-05 07:38:57 -0700 |
commit | 259ea9fed918cbbcf40e0596c8d2f8d3544996fb (patch) | |
tree | 412390713c586151a8d99abf191c83910283bad1 | |
parent | 49b98ad5a16ea8d6376cb66173d88b6d8cb2f822 (diff) | |
parent | 275df44b5798ddf09485d7ad503a212636ddf340 (diff) | |
download | psutil-259ea9fed918cbbcf40e0596c8d2f8d3544996fb.tar.gz |
merge from master
-rw-r--r-- | CREDITS | 4 | ||||
-rw-r--r-- | HISTORY.rst | 6 | ||||
-rw-r--r-- | docs/conf.py | 2 | ||||
-rw-r--r-- | docs/index.rst | 178 | ||||
-rw-r--r-- | psutil/__init__.py | 43 | ||||
-rw-r--r-- | psutil/_psutil_windows.c | 17 | ||||
-rw-r--r-- | psutil/_pswindows.py | 47 | ||||
-rwxr-xr-x | psutil/tests/test_process.py | 59 | ||||
-rwxr-xr-x | scripts/internal/.git-pre-commit | 3 |
9 files changed, 230 insertions, 129 deletions
@@ -603,3 +603,7 @@ I: 1470 N: Daniel Beer W: https://github.com/dbeer1 I: 1471 + +N: Samer Masterson +W: https://github.com/samertm +I: 1480 diff --git a/HISTORY.rst b/HISTORY.rst index b01d8fea..5741e247 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -10,6 +10,9 @@ the number of physical CPUs in case /proc/cpuinfo does not provide this info. - 1458_: provide coloured test output. Also show failures on KeyboardInterrupt. - 1464_: various docfixes (always point to python3 doc, fix links, etc.). +- 1473_: [Windows] process IO priority (ionice()) values are now exposed as 4 + new constants: IOPRIO_VERYLOW, IOPRIO_LOW, IOPRIO_NORMAL, IOPRIO_HIGH. + Also it was not possible to set high I/O priority (not it is). - 1478_: add make command to re-run tests failed on last run. **Bug fixes** @@ -22,10 +25,13 @@ exist. (patch by Cedric Lamoriniere) - 1471_: [SunOS] Process name() and cmdline() can return SystemError. (patch by Daniel Beer) +- 1474_: fix formatting of psutil.tests() which mimicks 'ps aux' output. - 1475_: [Windows] OSError.winerror attribute wasn't properly checked resuling in WindowsError being raised instead of AccessDenied. - 1477_: [Windows] wrong or absent error handling for private NTSTATUS Windows APIs. Different process methods were affected by this. +- 1480_: [Windows] psutil.cpu_count(logical=False) could cause a crash due to + fixed read violation. (patch by Samer Masterson) 5.6.1 ===== diff --git a/docs/conf.py b/docs/conf.py index df825cbd..b056d20f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -110,7 +110,7 @@ language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'DEVGUIDE.rst'] # The reST default role (used for this markup: `text`) to use for all # documents. diff --git a/docs/index.rst b/docs/index.rst index 6ff1e22c..85429eb6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -500,7 +500,7 @@ Network When the remote endpoint is not connected you'll get an empty tuple (AF_INET*) or ``""`` (AF_UNIX). For UNIX sockets see notes below. - **status**: represents the status of a TCP connection. The return value - is one of the :data:`psutil.CONN_* <psutil.CONN_ESTABLISHED>` constants + is one of the `psutil.CONN_* <#connections-constants>`_ constants (a string). For UDP and UNIX sockets this is always going to be :const:`psutil.CONN_NONE`. @@ -1173,7 +1173,7 @@ Process class .. method:: status() The current process status as a string. The returned string is one of the - :data:`psutil.STATUS_*<psutil.STATUS_RUNNING>` constants. + `psutil.STATUS_* <#process-status-constants>`_ constants. .. method:: cwd() @@ -1230,36 +1230,54 @@ Process class .. method:: ionice(ioclass=None, value=None) - Get or set process I/O niceness (priority). On Linux *ioclass* is one of the - :data:`psutil.IOPRIO_CLASS_*<psutil.IOPRIO_CLASS_NONE>` constants. - *value* is a number which goes from ``0`` to ``7``. The higher the value, - the lower the I/O priority of the process. On Windows only *ioclass* is - used and it can be set to ``2`` (normal), ``1`` (low) or ``0`` (very low). - The example below sets IDLE priority class for the current process, - meaning it will only get I/O time when no other process needs the disk: - - >>> import psutil - >>> p = psutil.Process() - >>> p.ionice(psutil.IOPRIO_CLASS_IDLE) # set - >>> p.ionice() # get - pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0) - >>> - - On Windows only *ioclass* is used and it can be set to ``2`` (normal), - ``1`` (low) or ``0`` (very low). Also it returns an integer instead of a - named tuple. - - Availability: Linux and Windows > Vista - - .. versionchanged:: - 3.0.0 on Python >= 3.4 the returned ``ioclass`` constant is an - `enum <https://docs.python.org/3/library/enum.html#module-enum>`__ - instead of a plain integer. + Get or set process I/O niceness (priority). + If no argument is provided it acts as a get, returning a ``(ioclass, value)`` + tuple on Linux and a *ioclass* integer on Windows. + If *ioclass* is provided it acts as a set. In this case an additional + *value* can be specified on Linux only in order to increase or decrease the + I/O priority even further. + Here's the possible platform-dependent *ioclass* values. + + Linux (see `ioprio_get`_ manual): + + * ``IOPRIO_CLASS_RT``: (high) the process gets first access to the disk + every time. Use it with care as it can starve the entire + system. Additional priority *level* can be specified and ranges from + ``0`` (highest) to ``7`` (lowest). + * ``IOPRIO_CLASS_BE``: (normal) the default for any process that hasn't set + a specific I/O priority. Additional priority *level* ranges from + ``0`` (highest) to ``7`` (lowest). + * ``IOPRIO_CLASS_IDLE``: (low) get I/O time when no-one else needs the disk. + No additional *value* is accepted. + * ``IOPRIO_CLASS_NONE``: returned when no priority was previously set. + + Windows: + + * ``IOPRIO_HIGH``: highest priority. + * ``IOPRIO_NORMAL``: default priority. + * ``IOPRIO_LOW``: low priority. + * ``IOPRIO_VERYLOW``: lowest priority. + + Here's an example on how to set the highest I/O priority depending on what + platform you're on:: + + import psutil + p = psutil.Process() + if psutil.LINUX + p.ionice(psutil.IOPRIO_CLASS_RT, level=7) + else: # Windows + p.ionice(psutil.IOPRIO_HIGH) + p.ionice() # get + + Availability: Linux, Windows Vista+ + + .. versionchanged:: 5.6.2 Windows accepts mew ``IOPRIO_*`` constants + including new ``IOPRIO_HIGH``. .. method:: rlimit(resource, limits=None) Get or set process resource limits (see `man prlimit`_). *resource* is one - of the :data:`psutil.RLIMIT_* <psutil.RLIM_INFINITY>` constants. + of the `psutil.RLIMIT_* <#process-resources-constants>`_ constants. *limits* is a ``(soft, hard)`` tuple. This is the same as `resource.getrlimit`_ and `resource.setrlimit`_ but can be used for any process PID, not only `os.getpid`_. @@ -2031,10 +2049,13 @@ Example code: Constants ========= +Operating system constants +-------------------------- + .. _const-oses: .. data:: POSIX -.. data:: WINDOWS .. data:: LINUX +.. data:: WINDOWS .. data:: MACOS .. data:: FREEBSD .. data:: NETBSD @@ -2051,7 +2072,7 @@ Constants .. data:: OSX - Alias for :const:`MACOS` (deprecated). + Alias for :const:`MACOS`. .. warning:: deprecated in version 5.4.7; use :const:`MACOS` instead. @@ -2075,6 +2096,9 @@ Constants .. versionchanged:: 3.4.2 also available on Solaris. .. versionchanged:: 5.4.0 also available on AIX. +Process status constants +------------------------ + .. _const-pstatus: .. data:: STATUS_RUNNING .. data:: STATUS_SLEEPING @@ -2091,51 +2115,28 @@ Constants .. data:: STATUS_WAITING (FreeBSD) .. data:: STATUS_SUSPENDED (NetBSD) - A set of strings representing the status of a process. - Returned by :meth:`psutil.Process.status()`. - - .. versionadded:: 3.4.1 STATUS_SUSPENDED (NetBSD) - .. versionadded:: 5.4.7 STATUS_PARKED (Linux) + Represent a process status. Returned by :meth:`psutil.Process.status()`. -.. _const-conn: -.. data:: CONN_ESTABLISHED -.. data:: CONN_SYN_SENT -.. data:: CONN_SYN_RECV -.. data:: CONN_FIN_WAIT1 -.. data:: CONN_FIN_WAIT2 -.. data:: CONN_TIME_WAIT -.. data:: CONN_CLOSE -.. data:: CONN_CLOSE_WAIT -.. data:: CONN_LAST_ACK -.. data:: CONN_LISTEN -.. data:: CONN_CLOSING -.. data:: CONN_NONE -.. data:: CONN_DELETE_TCB (Windows) -.. data:: CONN_IDLE (Solaris) -.. data:: CONN_BOUND (Solaris) + .. versionadded:: 3.4.1 ``STATUS_SUSPENDED`` (NetBSD) + .. versionadded:: 5.4.7 ``STATUS_PARKED`` (Linux) - A set of strings representing the status of a TCP connection. - Returned by :meth:`psutil.Process.connections()` (`status` field). +Process priority constants +-------------------------- .. _const-prio: -.. data:: ABOVE_NORMAL_PRIORITY_CLASS -.. data:: BELOW_NORMAL_PRIORITY_CLASS +.. data:: REALTIME_PRIORITY_CLASS .. data:: HIGH_PRIORITY_CLASS -.. data:: IDLE_PRIORITY_CLASS +.. data:: ABOVE_NORMAL_PRIORITY_CLASS .. data:: NORMAL_PRIORITY_CLASS -.. data:: REALTIME_PRIORITY_CLASS +.. data:: IDLE_PRIORITY_CLASS +.. data:: BELOW_NORMAL_PRIORITY_CLASS - A set of integers representing the priority of a process on Windows (see - `SetPriorityClass`_). They can be used in conjunction with - :meth:`psutil.Process.nice()` to get or set process priority. + Represent the priority of a process on Windows (see `SetPriorityClass`_). + They can be used in conjunction with :meth:`psutil.Process.nice()` to get or + set process priority. Availability: Windows - .. versionchanged:: - 3.0.0 on Python >= 3.4 these constants are - `enums <https://docs.python.org/3/library/enum.html#module-enum>`__ - instead of a plain integer. - .. _const-ioprio: .. data:: IOPRIO_CLASS_NONE .. data:: IOPRIO_CLASS_RT @@ -2157,12 +2158,22 @@ Constants Availability: Linux - .. versionchanged:: - 3.0.0 on Python >= 3.4 these constants are - `enums <https://docs.python.org/3/library/enum.html#module-enum>`__ - instead of a plain integer. +.. data:: IOPRIO_VERYLOW +.. data:: IOPRIO_LOW +.. data:: IOPRIO_NORMAL +.. data:: IOPRIO_HIGH + + A set of integers representing the I/O priority of a process on Linux. + They can be used in conjunction with :meth:`psutil.Process.ionice()` to get + or set process I/O priority. + + Availability: Windows + + .. versionadded:: 5.6.2 + +Process resources constants +--------------------------- -.. _const-rlimit: .. data:: RLIM_INFINITY .. data:: RLIMIT_AS .. data:: RLIMIT_CORE @@ -2187,6 +2198,33 @@ Constants Availability: Linux +Connections constants +--------------------- + +.. _const-conn: +.. data:: CONN_ESTABLISHED +.. data:: CONN_SYN_SENT +.. data:: CONN_SYN_RECV +.. data:: CONN_FIN_WAIT1 +.. data:: CONN_FIN_WAIT2 +.. data:: CONN_TIME_WAIT +.. data:: CONN_CLOSE +.. data:: CONN_CLOSE_WAIT +.. data:: CONN_LAST_ACK +.. data:: CONN_LISTEN +.. data:: CONN_CLOSING +.. data:: CONN_NONE +.. data:: CONN_DELETE_TCB (Windows) +.. data:: CONN_IDLE (Solaris) +.. data:: CONN_BOUND (Solaris) + + A set of strings representing the status of a TCP connection. + Returned by :meth:`psutil.Process.connections()` and + :func:`psutil.net_connections` (`status` field). + +Hardware constants +------------------ + .. _const-aflink: .. data:: AF_LINK diff --git a/psutil/__init__.py b/psutil/__init__.py index ab2ed349..a217a9e7 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -146,6 +146,10 @@ elif WINDOWS: from ._psutil_windows import NORMAL_PRIORITY_CLASS # NOQA from ._psutil_windows import REALTIME_PRIORITY_CLASS # NOQA from ._pswindows import CONN_DELETE_TCB # NOQA + from ._pswindows import IOPRIO_VERYLOW # NOQA + from ._pswindows import IOPRIO_LOW # NOQA + from ._pswindows import IOPRIO_NORMAL # NOQA + from ._pswindows import IOPRIO_HIGH # NOQA elif MACOS: from . import _psosx as _psplatform @@ -2437,8 +2441,25 @@ def test(): # pragma: no cover """List info of all currently running processes emulating ps aux output. """ + def bytes2human(n): + """ + >>> bytes2human(10000) + '9.8 K' + >>> bytes2human(100001221) + '95.4 M' + """ + symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') + prefix = {} + for i, s in enumerate(symbols): + prefix[s] = 1 << (i + 1) * 10 + for s in reversed(symbols): + if n >= prefix[s]: + value = float(n) / prefix[s] + return '%.1f%s' % (value, s) + return '%.1fB' % (n) + today_day = datetime.date.today() - templ = "%-10s %5s %4s %7s %7s %-13s %5s %7s %s" + templ = "%-10s %6s %5s %8s %8s %12s %5s %7s %s" attrs = ['pid', 'memory_percent', 'name', 'cpu_times', 'create_time', 'memory_info'] if POSIX: @@ -2446,7 +2467,7 @@ def test(): # pragma: no cover attrs.append('terminal') print(templ % ("USER", "PID", "%MEM", "VSZ", "RSS", "TTY", "START", "TIME", "COMMAND")) - for p in process_iter(attrs=attrs, ad_value=''): + for p in process_iter(attrs=attrs, ad_value=None): if p.info['create_time']: ctime = datetime.datetime.fromtimestamp(p.info['create_time']) if ctime.date() == today_day: @@ -2458,24 +2479,26 @@ def test(): # pragma: no cover cputime = time.strftime("%M:%S", time.localtime(sum(p.info['cpu_times']))) try: - user = p.username() + user = p.username()[:9] except Error: user = '' if WINDOWS and '\\' in user: user = user.split('\\')[1] - vms = p.info['memory_info'] and \ - int(p.info['memory_info'].vms / 1024) or '?' - rss = p.info['memory_info'] and \ - int(p.info['memory_info'].rss / 1024) or '?' - memp = p.info['memory_percent'] and \ - round(p.info['memory_percent'], 1) or '?' + + vms = bytes2human(p.info['memory_info'].vms) if \ + p.info['memory_info'] is not None else '' + rss = bytes2human(p.info['memory_info'].rss) if \ + p.info['memory_info'] is not None else '' + memp = round(p.info['memory_percent']) if \ + p.info['memory_percent'] is not None else '' + print(templ % ( user[:10], p.info['pid'], memp, vms, rss, - p.info.get('terminal', '') or '?', + p.info.get('terminal', '') or '', ctime, cputime, p.info['name'].strip() or '?')) diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index b1f8d650..53617c58 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -495,6 +495,7 @@ psutil_cpu_count_phys(PyObject *self, PyObject *args) { DWORD length = 0; DWORD offset = 0; DWORD ncpus = 0; + DWORD prev_processor_info_size = 0; // GetLogicalProcessorInformationEx() is available from Windows 7 // onward. Differently from GetLogicalProcessorInformation() @@ -533,13 +534,20 @@ psutil_cpu_count_phys(PyObject *self, PyObject *args) { } ptr = buffer; - while (ptr->Size > 0 && offset + ptr->Size <= length) { + while (offset < length) { + // Advance ptr by the size of the previous + // SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX struct. + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)\ + (((char*)ptr) + prev_processor_info_size); + if (ptr->Relationship == RelationProcessorCore) { ncpus += 1; } + + // When offset == length, we've reached the last processor + // info struct in the buffer. offset += ptr->Size; - ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)\ - (((char*)ptr) + ptr->Size); + prev_processor_info_size = ptr->Size; } free(buffer); @@ -3685,7 +3693,8 @@ void init_psutil_windows(void) module, "ERROR_INVALID_NAME", ERROR_INVALID_NAME); PyModule_AddIntConstant( module, "ERROR_SERVICE_DOES_NOT_EXIST", ERROR_SERVICE_DOES_NOT_EXIST); - + PyModule_AddIntConstant( + module, "ERROR_PRIVILEGE_NOT_HELD", ERROR_PRIVILEGE_NOT_HELD); PyModule_AddIntConstant( module, "WINVER", PSUTIL_WINVER); PyModule_AddIntConstant( diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 32b9f576..929e27d7 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -63,11 +63,14 @@ else: # http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx __extra__all__ = [ "win_service_iter", "win_service_get", + # Process priority "ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS", - "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS", - "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS", - "CONN_DELETE_TCB", - "AF_LINK", + "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS", "NORMAL_PRIORITY_CLASS", + "REALTIME_PRIORITY_CLASS", + # IO priority + "IOPRIO_VERYLOW", "IOPRIO_LOW", "IOPRIO_NORMAL", "IOPRIO_HIGH", + # others + "CONN_DELETE_TCB", "AF_LINK", ] @@ -112,6 +115,19 @@ if enum is not None: globals().update(Priority.__members__) +if enum is None: + IOPRIO_VERYLOW = 0 + IOPRIO_LOW = 1 + IOPRIO_NORMAL = 2 + IOPRIO_HIGH = 3 +else: + class IOPriority(enum.IntEnum): + IOPRIO_VERYLOW = 0 + IOPRIO_LOW = 1 + IOPRIO_NORMAL = 2 + IOPRIO_HIGH = 3 + globals().update(IOPriority.__members__) + pinfo_map = dict( num_handles=0, ctx_switches=1, @@ -660,7 +676,8 @@ def is_permission_err(exc): # it does, in which case the original exception was WindowsError # (which is a subclass of OSError). return exc.errno in (errno.EPERM, errno.EACCES) or \ - getattr(exc, "winerror", -1) == cext.ERROR_ACCESS_DENIED + getattr(exc, "winerror", -1) in (cext.ERROR_ACCESS_DENIED, + cext.ERROR_PRIVILEGE_NOT_HELD) def convert_oserror(exc, pid=None, name=None): @@ -984,17 +1001,19 @@ class Process(object): if HAS_PROC_IO_PRIORITY: @wrap_exceptions def ionice_get(self): - return cext.proc_io_priority_get(self.pid) + ret = cext.proc_io_priority_get(self.pid) + if enum is not None: + ret = IOPriority(ret) + return ret @wrap_exceptions - def ionice_set(self, value, _): - if _: - raise TypeError("set_proc_ionice() on Windows takes only " - "1 argument (2 given)") - if value not in (2, 1, 0): - raise ValueError("value must be 2 (normal), 1 (low) or 0 " - "(very low); got %r" % value) - return cext.proc_io_priority_set(self.pid, value) + def ionice_set(self, ioclass, value): + if value: + raise TypeError("value argument not accepted on Windows") + if ioclass not in (IOPRIO_VERYLOW, IOPRIO_LOW, IOPRIO_NORMAL, + IOPRIO_HIGH): + raise ValueError("%s is not a valid priority" % ioclass) + cext.proc_io_priority_set(self.pid, ioclass) @wrap_exceptions def io_counters(self): diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py index d264ce6d..25c70a25 100755 --- a/psutil/tests/test_process.py +++ b/psutil/tests/test_process.py @@ -380,6 +380,16 @@ class TestProcess(unittest.TestCase): (psutil.IOPRIO_CLASS_RT, 7)) with self.assertRaises(ValueError): p.ionice(psutil.IOPRIO_CLASS_IDLE, value=8) + # errs + self.assertRaisesRegex( + ValueError, "can't specify value with IOPRIO_CLASS_NONE", + p.ionice, psutil.IOPRIO_CLASS_NONE, 1) + self.assertRaisesRegex( + ValueError, "can't specify value with IOPRIO_CLASS_IDLE", + p.ionice, psutil.IOPRIO_CLASS_IDLE, 1) + self.assertRaisesRegex( + ValueError, "'ioclass' argument must be specified", + p.ionice, value=1) finally: p.ionice(psutil.IOPRIO_CLASS_BE) @@ -387,38 +397,29 @@ class TestProcess(unittest.TestCase): @unittest.skipIf(not WINDOWS, 'not supported on this win version') def test_ionice_win(self): p = psutil.Process() - original = p.ionice() - self.assertIsInstance(original, int) + self.assertEqual(p.ionice(), psutil.IOPRIO_NORMAL) try: - value = 0 # very low - if original == value: - value = 1 # low - p.ionice(value) - self.assertEqual(p.ionice(), value) - finally: - p.ionice(original) - - @unittest.skipIf(not HAS_IONICE, "not supported") - def test_ionice_errs(self): - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - if LINUX: - self.assertRaises(ValueError, p.ionice, 2, 10) - self.assertRaises(ValueError, p.ionice, 2, -1) - self.assertRaises(ValueError, p.ionice, 4) - self.assertRaises(TypeError, p.ionice, 2, "foo") - self.assertRaisesRegex( - ValueError, "can't specify value with IOPRIO_CLASS_NONE", - p.ionice, psutil.IOPRIO_CLASS_NONE, 1) + # base + p.ionice(psutil.IOPRIO_VERYLOW) + self.assertEqual(p.ionice(), psutil.IOPRIO_VERYLOW) + p.ionice(psutil.IOPRIO_LOW) + self.assertEqual(p.ionice(), psutil.IOPRIO_LOW) + try: + p.ionice(psutil.IOPRIO_HIGH) + except psutil.AccessDenied: + pass + else: + self.assertEqual(p.ionice(), psutil.IOPRIO_HIGH) + # errs self.assertRaisesRegex( - ValueError, "can't specify value with IOPRIO_CLASS_IDLE", - p.ionice, psutil.IOPRIO_CLASS_IDLE, 1) + TypeError, "value argument not accepted on Windows", + p.ionice, psutil.IOPRIO_NORMAL, value=1) self.assertRaisesRegex( - ValueError, "'ioclass' argument must be specified", - p.ionice, value=1) - else: - self.assertRaises(ValueError, p.ionice, 3) - self.assertRaises(TypeError, p.ionice, 2, 1) + ValueError, "is not a valid priority", + p.ionice, psutil.IOPRIO_HIGH + 1) + finally: + p.ionice(psutil.IOPRIO_NORMAL) + self.assertEqual(p.ionice(), psutil.IOPRIO_NORMAL) @unittest.skipIf(not HAS_RLIMIT, "not supported") def test_rlimit_get(self): diff --git a/scripts/internal/.git-pre-commit b/scripts/internal/.git-pre-commit index c3c605e0..c7d7d1ff 100755 --- a/scripts/internal/.git-pre-commit +++ b/scripts/internal/.git-pre-commit @@ -79,8 +79,9 @@ def main(): os.path.exists(x)] lineno = 0 + kw = {'encoding': 'utf8'} if sys.version_info[0] == 3 else {} for path in py_files: - with open(path) as f: + with open(path, 'rt', **kw) as f: for line in f: lineno += 1 # space at end of line |